我正在进行测试,并试图将字节数据发送到契约,以便它能够解析、存储变量并返回值。
实心码
pragma solidity 0.6.12;
contract testbyte {
function sendBytes(bytes calldata _data) external pure returns (address) {
(uint amountIn, uint amountOut, address pool) = abi.decode(_data, (uint, uint, address));
return pool;
}
}
我在这里看到了这个答案,但是传递字节数据是在Javascript中完成的。将实体字节解析为仿射
Python代码
w3 = Web3(Web3.HTTPProvider(node_provider))
# I collect all data, abi, etc in between.
data = {
'amountIn': 1,
'amountOut': 2,
'pool': 'pool address here'
}
# I usually do w3.toBytes(text='') to pass nothing on mainnet contracts.
bytes_data = w3.toBytes(text=str(data))
pool = contract.functions.sendBytes(bytes_data).call()
print(pool)
我得到字节输出
b"{'amountIn': 1, 'amountOut': 2, 'pool': 'pool address here'}"
如果我试图通过合同恢复,如果我试图通过混音,我会得到
transact to testbyte.sendBytes errored: Error encoding arguments: Error: invalid arrayify value (argument="value", value="{'amountIn': 1, 'amountOut': 2, 'pool': 'pool address here'}", code=INVALID_ARGUMENT, version=bytes/5.5.0)
通过研究,我只能猜测我的字节输入是不正确的,或者合同中的某些东西是错误的,但我不确定。
在查看了注释中的示例之后,我在这里结束了:web3py编码方法调用参数
我试着用第二种方法,但我得到了合同的恢复。
test_encode = encode_abi(['uint', 'uint', 'address'], [1, 2, '0xAD5ce863aE3E4E9394Ab43d4ba0D80f419F61789'])
contract.functions.sendBytes(test_encode).call()
当我尝试第一种方法和第二种方法混合时
contract.encodeABI(fn_name='sendBytes', args=[test_encode])
它回来了
0x4c93893a0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000ad5ce863ae3e4e9394ab43d4ba0d80f419f61789
随机地,我输入它到混合它返回值,但所有错误的值。
因此,我仍然感到困惑,js部分似乎更容易。使用程序集从Bytes恢复数据
当我将输出输入到混合中时,这段代码可以工作。
test_encode = encode_abi(['uint', 'uint', 'address'], [1, 2, '0xAD5ce863aE3E4E9394Ab43d4ba0D80f419F61789'],)
contract.encodeABI(fn_name='sendBytes', args=[test_encode], data=test_encode)
产出:
0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000ad5ce863ae3e4e9394ab43d4ba0d80f419f617890000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000ad5ce863ae3e4e9394ab43d4ba0d80f419f61789
当进入混合时,它返回正确的值!但是现在我不知道如何在web3.py电话中传递数据。我一直在执行死刑。
发布于 2022-02-16 23:52:33
找到答案了。看来我的合同地址在我的.env文件中是错误的。更正后,我使用了下面的代码。
from eth_abi import encode_abi
test_encode = encode_abi(['uint', 'uint', 'address'], [1, 2, '0xAD5ce863aE3E4E9394Ab43d4ba0D80f419F61789'],) # Basically map the types to the values
pool = contract.functions.sendBytes(test_encode).call()
print(pool)
输出
['0xAD5ce863aE3E4E9394Ab43d4ba0D80f419F61789']
如果您想使用数组,可以这样做。
test_encode = encode_abi(['uint[]', 'uint[]', 'address'], [[1,2], [3,4], '0xAD5ce863aE3E4E9394Ab43d4ba0D80f419F61789'],)
我不能用
contract.encodeABI(fn_name='sendBytes', args=[test_encode], data=test_encode)
我相信我用错了它,它输出的数据是一个字符串。当您将值输入到混合中时,它会工作。我只能假设混合处理事情不同。也许有人可以解释如何在评论中正确地使用这一点。
https://ethereum.stackexchange.com/questions/121718
复制相似问题