我正在尝试执行某个操作,例如仅在发送到合同的消息由合同所有者签署时才出售代币。我知道如何在 js 中做到这一点,但我很难找到明确的 python 文档。这是我目前所拥有的。
我的坚定
function buy_token(string memory tokenURI, bytes memory signature) payable public{
// Make sure this token uri is signed by the owner of the contract
// to the recipient that is asking to buy
address signer_address = recoverSigner(keccak256(abi.encodePacked(tokenURI, msg.sender)), signature);
require(signer_address == minter, "NFT not authorized by this contract");
require(msg.value >= cprice, "Insufficient funds to buy");
require(minter != msg.sender, "Cant sell to owner");
uint256 mint_id = mint(tokenURI);
// transfer the token to the buyer
_transfer(minter, msg.sender, mint_id);
}
// functions from documentatations
function recoverSigner(bytes32 message, bytes memory sig)
public
pure
returns (address)
{
uint8 v;
bytes32 r;
bytes32 s;
(v, r, s) = splitSignature(sig);
return ecrecover(message, v, r, s);
}
function splitSignature(bytes memory sig)
public
pure
returns (uint8, bytes32, bytes32)
{
require(sig.length == 65, 'Wrong byte lenght');
bytes32 r;
bytes32 s;
uint8 v;
assembly {
// first 32 bytes, after the length prefix
r := mload(add(sig, 32))
// second 32 bytes
s := mload(add(sig, 64))
// final byte (first byte of the next 32 bytes)
v := byte(0, mload(add(sig, 96)))
}
return (v, r, s);
}
这是我的 python brownie 代码,它试图模拟部署者和用户。部署者签署消息并将其提供给用户,用户尝试使用签署的消息购买代币。
from brownie import Contract, accounts
from web3.auto import w3
from eth_account.messages import encode_defunct
from eth_abi.packed import encode_abi_packed
from eth_utils import keccak
def main():
# This part is for test in the real program the smart
# contract would alredy be deployed
deployer = accounts.add()
Contract.deploy({
'from':deployer
})
msg = """JSON FORMATED STRING"""
hash = keccak(encode_abi_packed(['string','address'],[tokenURI, accounts[0].address]))
message = encode_defunct(text=hash.hex())
signed_message = w3.eth.account.sign_message(message, private_key=deployer.private_key)
signed = str(signed_message.messageHash.hex())
tx = Contract[0].buy_token(tokenURI, signed,{'from':accounts[0], 'value': Contract[0].cprice() + 10000000000})
print(tx.info, tx.events)
我已经尝试了类似帖子中建议的所有方法,但我无法让它们工作,当前错误是由以下行引发的。
require(sig.length == 65, 'Wrong byte lenght');
但是我尝试的所有方法都会生成长度为 66 的签名消息。