0

我正在尝试执行某个操作,例如仅在发送到合同的消息由合同所有者签署时才出售代币。我知道如何在 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 的签名消息。

4

0 回答 0