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