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();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/328329.html
標籤:區塊鏈
