[native]'元交易'与'原生'的转账gas消耗测试

2021-10-21  本文已影响0人  95加不满

结果:transfer < metaTransferMy < metaTransfer
初步可以肯定:正常情况下metaTransfer不会达到transfer的2倍。(当然gas的消耗与执行的代码量有关。)

测试

  1. metaTransfer
to  MetaCoin.metaTransfer(bytes,address,uint256,uint256,uint256) 0xd9145CCE52D386f254917e481eB44e9943F39138 
 gas    80000000 gas 
 transaction cost   50496 gas 
 execution cost 50496 gas 
  1. metaTransferMy
 to MetaCoin.metaTransferMy(address,address,uint256,uint256) 0xd9145CCE52D386f254917e481eB44e9943F39138 
 gas    80000000 gas 
 transaction cost   38537 gas
 execution cost 38537 gas 
  to    MetaCoin.metaTransferMy(address,address,uint256,uint256) 0xd9145CCE52D386f254917e481eB44e9943F39138 
 gas    80000000 gas 
 transaction cost   35376 
 execution cost 35376 gas 
  1. transfer
 to MetaCoin.transfer(address,uint256) 0xd9145CCE52D386f254917e481eB44e9943F39138 
 gas    80000000 gas 
 transaction cost   34961 
 execution cost 34961 gas 

合约代码

pragma solidity ^0.4.24;

import "openzeppelin-solidity/contracts/token/ERC20/ERC20Mintable.sol";

contract MetaCoin is ERC20Mintable {

  string public name = "MetaCoin";
  string public symbol = "MC";
  uint8 public decimals = 0;

  constructor() public {

  }

  mapping (address => uint256) public replayNonce;

  function metaTransfer(bytes signature, address to, uint256 value, uint256 nonce, uint256 reward) public returns (bool) {
    bytes32 metaHash = metaTransferHash(to,value,nonce,reward);
    address signer = getSigner(metaHash,signature);
    //make sure signer doesn't come back as 0x0
    require(signer!=address(0));
    require(nonce == replayNonce[signer]);
    replayNonce[signer]++;
    _transfer(signer, to, value);
    if(reward>0){
      _transfer(signer, msg.sender, reward);
    }
  }
  function metaTransferMy(address from, address to, uint256 value, uint256 reward) public returns (bool) {
    _transfer(from, to, value);
    if(reward>0){
      _transfer(from, msg.sender, reward);
    }
  }
  function metaTransferHash(address to, uint256 value, uint256 nonce, uint256 reward) public view returns(bytes32){
    return keccak256(abi.encodePacked(address(this),"metaTransfer", to, value, nonce, reward));
  }

  /*
  function metaApprove(address spender, uint256 value, uint256 nonce, uint256 reward, bytes signature) public returns (bool) {
    require(spender != address(0));
    bytes32 metaHash = metaApproveHash(spender,value,nonce,reward);
    address signer = getSigner(metaHash,signature);
    require(nonce == replayNonce[signer]);
    replayNonce[signer]++;
    _allowed[signer][spender] = value;
    if(reward>0){
      _transfer(signer, msg.sender, reward);
    }
    emit Approval(msg.sender, spender, value);
    return true;
  }
  function metaApproveHash(address spender, uint256 value, uint256 nonce, uint256 reward) public view returns(bytes32){
    return keccak256(abi.encodePacked(address(this),"metaApprove" spender, value, nonce, reward));
  }
  */

  function getSigner(bytes32 _hash, bytes _signature) public pure returns (address){
    bytes32 r;
    bytes32 s;
    uint8 v;
    if (_signature.length != 65) {
      return address(0);
    }
    assembly {
      r := mload(add(_signature, 32))
      s := mload(add(_signature, 64))
      v := byte(0, mload(add(_signature, 96)))
    }
    if (v < 27) {
      v += 27;
    }
    if (v != 27 && v != 28) {
      return address(0);
    } else {
      return ecrecover(keccak256(
        abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash)
      ), v, r, s);
    }
  }

}
上一篇 下一篇

猜你喜欢

热点阅读