介绍
区块链智能合约相关题目,挺有意思,简单分享。
题目
题目内包含两个链接:
https://github.com/paradigmxyz/paradigm-ctf-infrastructure
对应后端服务搭建相关,只看eth-challenge-base目录即可。
random.zip,合约代码内容,也是题目关键,合约代码贴在后面。
实现&分析
nc连接返回三个选项
1 - launch new instance
2 - kill instance
3 - get flag
1:表示启动一个实例,就是具体实现见后端代码,我理解就是部署了智能合约,会返回以下几个参数:
uuid:唯一标示,实例校验使用。
rpc endpoint: 理解为智能合约节点地址,通过该地址可以访问智能合约。
private key: 钱包地址私钥
setup contract: 智能合约的地址。
2:删掉当前实例。
3:返回flag。
返回flag的前提
前面校验不细讲,关键是这里。
查看具体代码是:
def is_solved_checker(web3: Web3, addr: str) -> bool:
result = web3.eth.call(
{
"to": addr,
"data": web3.sha3(text="isSolved()")[:4],
}
)
return int(result.hex(), 16) == 1
调用合约Setup.isSolved返回true。
思路
两个合约代码如下:
contract Setup {
Random public random;
constructor() {
random = new Random();
}
function isSolved() public view returns (bool) {
return random.solved();
}
}
contract Random {
bool public solved = false;
function _getRandomNumber() internal pure returns (uint256) { // chosen by fair dice roll.
return 4; // guaranteed to be random.
}
function solve(uint256 guess) public {
require(guess == _getRandomNumber());
solved = true;
}
}
从代码看,基本就是调用Random.solve(4),即解决问题。
因此实现先获取返回的合约地址拿到当前的Setup实例(个人理解,不一定对)
contract2 = web3.eth.contract(address=contract, abi=config["abi"])
接着获取其中的random对象,也就是Random实例的合约地址,
randomAddress = contract2.functions.random().call()
然后调用random.solve(4)。
contract1 = web3.eth.contract(address=randomAddress, abi=config1["abi"])
result = contract1.functions.solve(4).transact()
这里调用不能像上面一样调用call,是因为带有参数需要调用transact,正常交易还需要往里面填入gas才能发起(个人理解)。文章来源:https://www.toymoban.com/news/detail-734835.html
writeup
from socket import *
from web3 import Web3
from eth_utils import *
from eth_typing import *
uuid = "XXXX"
url = "http://34.66.135.107:8545/" + uuid
pkey = "xxxx"
contract = "xxxx"
ticket = "xxxx"
header = {'Content-type':'application/json'}
config = {
"abi":
[
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "isSolved",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "random",
"outputs": [
{
"internalType": "contract Random",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
]
}
config1 = {"abi":[
{
"inputs": [
{
"internalType": "uint256",
"name": "guess",
"type": "uint256"
}
],
"name": "solve",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "solved",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}]
}
web3 = Web3(Web3.HTTPProvider(url))
contract2 = web3.eth.contract(address=contract, abi=config["abi"])
result = contract2.functions.isSolved().call()
print(result)
randomAddress = contract2.functions.random().call()
print(randomAddress)
contract1 = web3.eth.contract(address=randomAddress, abi=config1["abi"])
# result = contract1.functions.solve(4).call()
result = contract1.functions.solve(4).transact()
print(result)
result = contract1.functions.solved().call()
print(result)
总结
一直没有时间学习智能合约这块,通过比赛反而带动学习兴趣,也找到一些学习的方向。文章来源地址https://www.toymoban.com/news/detail-734835.html
到了这里,关于【2022Paradigm.ctf】random writeup的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!