solidity数据类型msg tx hash kill payable new

Posted blockchain_yhj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了solidity数据类型msg tx hash kill payable new相关的知识,希望对你有一定的参考价值。

1 区块与交易信息

区块相关属性
区块的矿工地址、区块号、gaslimit、难度值、时间戳
blockhash(uint) 取最新的256个区块号对应的hash,但不包括当前区块的
block.coinbase/block.difficulty/block.gaslimit/block.number/block.timestamp/now 都是取当前区块的相关信息

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.4.0;
contract timeTest{
    function getNow()public  view returns(uint256){
        return now;
    }
    function getTimestamp()public view returns(uint256){
        return block.timestamp;
    } 
    function getBlockHash()public view returns(bytes32){
        return blockhash(32);
    }
    function getBlockCoinbase()public view returns(address){
        return block.coinbase;
    }
    function getDifficulty()public view returns(uint256){
        return block.difficulty;
    }
    function getBlockGasLimit()public view returns(uint256){
        return block.gaslimit;
    }
    function getBlockNumber()public view returns(uint256){
        return block.number;
    }
}

消息msg的相关属性
gasleft() 交易带的gas值减去交易执行到现在的gas
msg.data 完整的calldata,ABI编码 字节数组
msg.sender/msg.sig(calldata前4个字节 函数选择器)/msg.value

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.4.0;
contract MsgTest{
    function msgData()public pure returns(bytes memory){
        return msg.data;
    }
    function getBalance()public view returns(address,uint256){
        return (msg.sender,msg.sender.balance);
    }
    function getGasleft()public view returns(uint256){
        return gasleft();
    }
    function getMsgsig()public pure returns(bytes4){
        return msg.sig;
    }
    function getMsgValue()public payable returns(uint256){
        return msg.value;
    }
}

交易的相关信息
获取当前交易的gasPrice
获取交易发起者
msg.sender的owner可以是一个合约;而tx.origin的owner不可能是一个合约。在一个简单的调用链中,A->B->C->D,D里面的msg.sender将会是C,而tx.origin将一直是A
tx.origin遍历整个调用栈并返回最初发送调用(或事务)的帐户的地址

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.4.0;
contract TxContract{
    function txGasPrice()public view returns(uint256){
        return tx.gasprice;
    }
    function txOrigin()public view returns(address){
        return tx.origin;
    }
}


2 转账货币单位

// 1 wei 1 ether =1e18 wei
// 1 szabo 1 ether= 1e6 szabo
// 1 finney 1 ether=1e3 finney
// 1 ether

3 事件日志

事件是可以被继承的,当事件被调用时,事件的参数会记录在交易日志中,日志与合约的地址关联,并且被永久的存储在区块链中,
通过event关键字标识事件
indexed、anonymous、emit关键字都和事件主题相关
一个事件最多有4个主题,所以事件参数最多有三个参数可以使用indexed关键字,第一个主题是时间签名,其余的时所印花的参数数值
anonymous关键字的作用是不把事件签名作为第一个主题,则最多有4个参数可以使用indexed关键字。
emit用来抛出事件

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.4.0;
contract EventTest{
    event LogEvent(string indexed first,uint indexed second,uint8 third,uint8 indexed fourth);
    event LogAnonymousEvent(string indexed first,uint indexed second,uint8 third,uint8 indexed fourth) anonymous;
    function eventFunction()public{
        emit LogEvent("LogEvent",10,12,11);
    }
    function anonymousEventFunction()public{
        emit LogAnonymousEvent("Logevent",10,12,11);
    }
    function getSig()public pure returns(bytes32 r1,bytes32 r2){
        r1=keccak256("LogEvent(string,uint256,uint8,uint8)");
        r2=keccak256("LogEvent");
    }
}

LogEvent事件签名:

0x27dde014b058f20e9caf4e7689ed63584d1307732877fce3dee00ee57eca42e4

LogEvent字符串的哈希值:

0x9cc4d20bed33e9cc82468fe65d2388e059e1d57da74f9eaf654ad6bd19bd337f

执行LogEvent函数 查看日志信息:

topic就是事件签名
对于indexed的字符串,采用哈希存储
整型数据,存储原值
事件的indexed参数会出现在返回值的topics中
非indexed参数在返回值的data属性中

[
{
“from”: “0x9396B453Fad71816cA9f152Ae785276a1D578492”,
“topic”: “0x27dde014b058f20e9caf4e7689ed63584d1307732877fce3dee00ee57eca42e4”,
“event”: “LogEvent”,
“args”: {
“0”: {
“_isIndexed”: true,
“hash”: “0x9cc4d20bed33e9cc82468fe65d2388e059e1d57da74f9eaf654ad6bd19bd337f”
},
“1”: “10”,
“2”: 12,
“3”: 11
}
}
]

执行anonymous函数,查看日志信息:

作用就是gas 更低。
默认的的事件都会有索引, anonymous event 就是指明不加事件签名索引
非indexed参数填充为16进制的32字节数据放在data中
indexed数据放在topics中
[
{
“from”: “0x9396B453Fad71816cA9f152Ae785276a1D578492”,
“data”: “0x000000000000000000000000000000000000000000000000000000000000000c”,
“topics”: [
“0x221da71391b22d8b3ef2372e12a4e8fe5f1e8afbcf24cf8e0744a975078592b0”,
“0x000000000000000000000000000000000000000000000000000000000000000a”,
“0x000000000000000000000000000000000000000000000000000000000000000b”
]
}
]

4 solidity加密函数

运算函数
addmod(a,b,n) (a+b)mod n
mulmod(a,b,n) (a*b)mod n

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.4.0;
contract MAthCopntract{
    function testAddMod(uint a,uint b, uint n)public pure returns(uint){
        return addmod(a,b,n);
    }
        function testMulMod(uint a,uint b, uint n)public pure returns(uint){
        return mulmod(a,b,n);
    }
}

hash函数
keccak256 和 sha3 等价 返回256位 32字节数据
sha256返回256位32字节加密数据
ripemd160返回160位20字节加密数据

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.4.0;
contract hashContract{
    function testKeccak256()public pure returns(bytes32,bytes32){
        return (keccak256("testKeccak256()"),keccak256("abc"));
    }
    function testSha3()public pure returns(bytes32,bytes32){
        return (sha3("testKeccak256()"),sha3("abc"));
    }
    function testSha256()public pure returns(bytes32){
        return sha256("testKeccak256()");
    }
    function testRipemd160()public pure returns(bytes20){
        return ripemd160("testKeccak256()");
    }
}

ecrecover 函数从签名数据中恢复签名使用的私钥对应的地址
地址私钥签名的数据返回三部分:r、s、v
r、s32字节 v最后一个字节

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.4.0;
contract RecoveryContract {
    
    function testRecovery() public pure returns(address){
        bytes memory prefix = "\\x19Ethereum Signed Message:\\n5";
        bytes5 data = 0x48656c6c6f;
        bytes32 h = keccak256(prefix,data);
        uint8 v = 28;
        bytes32 r = 0xf63e45ffd92b2bd6e0ec14e9b85c88fe1f7fb9a72783b6e1508120451f6d3d49;
        bytes32 s = 0x505d8645d648e9d77216f7a17a9d21e99ffa63b92ded7024e8174da2f2c1f2cb;
        address addr = ecrecover(h, v, r, s);
        return addr;
    }
}

5 以太坊ABI(application binary interface)

abi是以太坊生态系统中与合约交互的标准方式,包括区块链外部调用和合约之间的交互

6 合约函数

回退函数
一个合约有且最多能有一个不命名的函数,函数无参数、无返回,这个函数就是一个回退函数
回退函数在执行以太币接受时会被调用,接受以太币必须添加payable修饰符
当在合约上执行一个函数调用,当没有函数匹配的时候,合约的回退函数就会被调用
回退函数只有2300gas的限制 除记录日志外没有太多gas执行额外操作

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.4.0;
contract FallbackWithoutPayableContract {
    uint8 public num = 0;
    event LogUint8(uint8 num);
    function() public { 
        emit LogUint8(num);
        num++;
    }
}
contract FallbackContract {
    function() public payable{ 
    }
    function getBalance() public view returns(uint256){
        return address(this).balance;
    }
}
contract CallerContract {
    function callFallbackWithoutPayableContract(FallbackWithoutPayableContract con) public {
        address(con).call(0xaabbccdd);
        //con.send(2 ether);
    }
    function callFallbackContract(FallbackContract con) public {
        con.call(0xaabbccdd);
        con.send(2 ether);
    }
}

析构函数
用来销毁合约
调用析构函数将合约账户中的余额转移到指定的地址

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.4.0;
contract DestroyContract {
  //构造器
     constructor() public payable{
    }
//析构函数  销毁合约
    function kill(address recipit) public{
        // suicide(recipit);
        selfdestruct(recipit);
    }
    //获取合约账户的余额
    function getBalance() public view returns(uint256){
        return address(this).balance;
    }
    //回退函数
    function() public payable{ 
    }
}
contract ReceiveContract {
    function() public{   
    }
}
contract TransferContract {
    constructor() public payable{   
    }
    //执行接受以太坊需要payable修饰符
    function transferEther(address addr) public payable{
        addr.transfer(1 ether);
    }
    function() public payable{
    }
}

通过new创建合约
在创建合约时可以转部分值
新合约继承父合约的状态变量
新合约拥有独立的合约账户

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.4.0;
contract BaseContract {
      uint256 public count = 0;
      address public owner;
      mapping(uint256=>string) public data;
      constructor() public payable {
          owner = msg.sender;
          data[1] = "hello";
      }
      //接受以太币需要payable修饰符
      function sendAmount(address addr) public payable{
          addr.transfer(1000 wei);
      }
      function add(uint256 a,uint256 b) public pure returns(uint256){
          return a + b;
      }
      function getBalance() public view returns(uint256){
          return address(this).balance;
      }
      function addCount(uint256 num) public{
          count += num;
      }
       function modifiyOwner(address addr) public{
          owner = addr;
      }
      function putData(uint256 id,string name) public{
          data[id] = name;
      }
      function getData(uint256 id) public view returns(string){
          return data[id];
      }
      //析构函数
      function kill() public{
          selfdestruct(msg.sender);
      }
}

contract NewContract {
//合约类型
    BaseContract public base;
    function newBaseContract() public payable{
        base = (new BaseContract).value(0 wei)(); 
    } 
    function callSendAmounts(address addr) public payable{
         base.sendAmount(addr);
    }
    function callAdd(uint256 a,uint256 b) public view returns(uint256){
        return base.add(a,b);
    }
    function callGetBalance() public view returns(uint256){
        return base.getBalance();
    }
        function callAddCount(uint256 num) public{
        base.addCount(num);
    }
    
    function callModifiyOwner(address addr) public{
        base.modifiyOwner(addr);
    }
    function callPutData(uint256 id,string name) public{
        base.putData(id,name);
    }
    function callGetData(uint256 id) public view returns(string){
        return base.getData(id);
    }
    function getCount() public view returns(uint256){
        return base.count();
    }
    function callKill() public{
        base.kill();
    }
}

以上是关于solidity数据类型msg tx hash kill payable new的主要内容,如果未能解决你的问题,请参考以下文章

以太坊 solidity msg对象

solidity二固定长度数组动态长度数组字符串之间的转换solidity字典hash表的使用solidity——memorystorage使用注意项solidity状态变量局部变量

solidity智能合约中tx.origin的正确使用场景

Solidity极简入门#6. 引用类型

Solidity 基础知识:“msg.sender”代表啥

如何在solidity 0.5.0中将etherenum发送到msg.sender