繁体   English   中英

使用 solidity 和 python 签署并验证消息

[英]sign and verify message with solidity and python

我正在尝试执行某个操作,比如仅当发送到合同的消息由合同所有者签署时才出售令牌。 我知道如何在 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 布朗尼代码,它试图模拟部署者和用户。 部署者签署消息并将其提供给用户,用户尝试使用签名消息购买令牌。

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 的签名消息。

应该是signed_message.signature.hex()而不是signed_message.messageHash.hex()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM