摘要:上一篇我們講了中的參數含義以太坊介紹一,但是只有函數定義也是不行的,我們還需要調用,當調用一個函數時也需要對該函數進行編碼,這樣才能執行,那么以太坊是如何生成可供調用的字節碼的。
上一篇我們講了ABI中的參數含義 以太坊ABI介紹(一),但是只有函數定義也是不行的,我們還需要調用,當調用一個函數時也需要對該函數進行編碼,這樣EVM才能執行,那么以太坊是如何生成可供EVM調用的字節碼的。
生成的字節碼主要分兩部分:函數選擇器和參數編碼
函數選擇器即函數編碼,對函數名稱+參數類型進行sha3(keccak256)哈希運算之后,取前4個字節
1、方法一:
安裝pyethereum [https://github.com/ethereum/p...]
> from ethereum.utils import sha3 > sha3("set(uint256").hex() "0x60fe47b16ed402aae66ca03d2bfc51478ee897c26a1158669c7058d5f24898f4" > sha3("setA(uint256)")[0:4].hex() "60fe47b1"
2、方法二:
打開Ganache,默認端口7545,然后再命令行執行以下命令
curl -X POST -i http://localhost:7545 --data "{ "jsonrpc":"2.0", "method":"web3_sha3", "params":["set(uint256)"] }" 返回結果: { "jsonrpc": "2.0", "result": "0x60fe47b16ed402aae66ca03d2bfc51478ee897c26a1158669c7058d5f24898f4" }
3、方法三:
const Web3 = require("web3") const web3 = new Web3() console.log(web3.sha3("set(uint256)")) # 0x60fe47b16ed402aae66ca03d2bfc51478ee897c26a1158669c7058d5f24898f4
取前四個字節(一個字節=2個16進制字符)即:0x60fe47b1
參數編碼由于函數編碼占用了4個字節,所以參數編碼從第五位開始
參數的編碼根據類型的不同,編碼方式也有所區別。主要分為固定類型和動態類型
1、固定類型
uint
int
uint和int:整型,分別是uint256和int256的別名。注意: 函數參數類型是uint,轉sha3碼時要變成uint256。
address:地址,20個字節,160bits。
bool:布爾類型,1個字節,true:1,false:0。高位補0
bytes 2、動態類型 bytes:動態分配大小字節數組。不是一個值類型! string:動態大小UTF8編碼的字符串,不是一個值類型! T[] 某個類型的不定長數組 T[k] 某個類型的定長數組 固定類型的編碼就很簡單,直接將參數值轉成32字節長度的16進制即可。但是有區別的是:不足32bytes時,數字類型,如果是正數高位補0,如果是負數高位補1,布爾類型高位補0,字節類型、字符串類型在低位補全 介紹的例子和官方文檔一樣,如果理解有偏差可以查看源文檔 案例一:
0xcdcd77c0,在node中使用new Web3().sha3("baz(uint32,bool)")生成
0x0000000000000000000000000000000000000000000000000000000000000045,十進制69,轉成16進制為45,因為是正數,高位補0至32bytes
0x0000000000000000000000000000000000000000000000000000000000000001,bool類型,true=1,false=0,高位補0 所以最終字符串為:(換行顯示是為了方便查看,實際是沒有換行) 返回:該函數返回的是true,output將會是 案例二:
0xfce353f6,在node中使用new Web3().sha3("bar(bytes3[2])")生成 固定長度不需要計算偏移量
0x6162630000000000000000000000000000000000000000000000000000000000,字符串abc轉成16進制后為616263,低位補0,字符串轉16進制可以使用這個工具
0x6465660000000000000000000000000000000000000000000000000000000000,同上 所以最終字符串為:(換行顯示是為了方便查看,實際是沒有換行) 案例三:
0x8be65246,在node中使用f(uint256,uint32[],bytes10,bytes)生成
0x0000000000000000000000000000000000000000000000000000000000000123,0x123對應的16進制,正數補全
0x0000000000000000000000000000000000000000000000000000000000000080,動態類型,計算偏移量。這個的偏移量是指實際存儲值的位置,由于這個函數有4個變量,那么實際存儲值的位置就是第五個32bytes位置,也就是說偏移量等于4*32bytes=128,轉成16進制后就是對應的值
0x3132333435363738393000000000000000000000000000000000000000000000,字符串1234567890轉成16進制后為31323334353637383930,bytes類型,低位補全
0x00000000000000000000000000000000000000000000000000000000000000e0,動態類型,計算偏移量,這個偏移量就等于參數長度4*32bytes+前面的動態參數參數占有的長度(因為前面只有一個動態參數,所以這個長度就是1*32bytes+2*32bytes,1*32bytes是第一個動態參數長度所占的bytes數,2*32bytes是因為該函數中的第一個動態參數有2個值),那么具體的值就是 4*32bytes+(1*32bytes+2*32bytes)=7*32bytes=224,轉成16進制就是e0,高位補全就是對應的值
0x0000000000000000000000000000000000000000000000000000000000000002,第一個動態參數的長度,長度為2
0x0000000000000000000000000000000000000000000000000000000000000456,第一個動態參數中的第一個元素
0x0000000000000000000000000000000000000000000000000000000000000789,第一個動態參數中的第二個元素
0x000000000000000000000000000000000000000000000000000000000000000d,第二個動態參數的長度,長度為13
0x48656c6c6f2c20776f726c642100000000000000000000000000000000000000,第二個動態參數的值編碼 所以最終字符串為:(換行顯示是為了方便查看,實際是沒有換行) 以上就是以太坊調用函數時生成字節碼的完整過程了!編碼規則
動態類型的編碼稍微復雜點,如果是固定長度就不需要計算偏移量,如果是不定長度就需要先計算偏移量,并在最后加上長度和具體值的編碼,詳細步驟下面會介紹具體編碼過程
pragma solidity ^0.4.16;
contract Foo {
function baz(uint32 x, bool y) public pure returns (bool r) { r = x > 32 || y; }
function bar(bytes3[2] memory) public pure {}
function f(uint, uint32[], bytes10, bytes) public pure {}
}
案例
函數:baz(bytes3[2] memory)
調用:baz(69, true)const Web3 = require("web3")
const web3 = new Web3()
console.log(web3.sha3("f(uint256,uint32[],bytes10,bytes)"))
0xcdcd77c0
0x0000000000000000000000000000000000000000000000000000000000000045
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000000000000000000000000000000000000000000000000000000000000000
函數:bar(bytes3[2] memory)
調用:bar(["abc", "def"])0xfce353f6
0x6162630000000000000000000000000000000000000000000000000000000000
0x6465660000000000000000000000000000000000000000000000000000000000
函數:f(uint,uint32[],bytes10,bytes)
調用:f(0x123, [0x456, 0x789], "1234567890", "Hello, world!")0x8be65246
0000000000000000000000000000000000000000000000000000000000000123
0000000000000000000000000000000000000000000000000000000000000080
3132333435363738393000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000e0
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000456
0000000000000000000000000000000000000000000000000000000000000789
000000000000000000000000000000000000000000000000000000000000000d
48656c6c6f2c20776f726c642100000000000000000000000000000000000000
歡迎訂閱「K叔區塊鏈」 - 專注于區塊鏈技術學習
博客地址:http://www.jouypub.com
簡書主頁:https://www.jianshu.com/u/756c9c8ae984
segmentfault主頁:https://segmentfault.com/blog/jouypub
騰訊云主頁:https://cloud.tencent.com/developer/column/72548
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/24343.html
摘要:但是對于調用者來說,就需要知道合約有哪些方法,方法的參數是什么,返回值是什么,而這些信息就記錄在智能合約的中。 ABI是什么 ABI全稱 Application Binary Interface,字面意思是應用程序二進制接口,可以通俗的理解為合約的接口說明,當合約被編譯后,它對應的abi也就確定了。abi有點類似于程序中的接口文檔,描述了字段名稱、字段類型、方法名稱、參數名稱、參數類型...
摘要:合約規定了公共職能部門,以創造新的投資和撤資,這將成為對沖基金的主要職能。對沖基金的用戶通過其以太坊地址來識別,該地址相當于公鑰。我發現與其他程序如程序的以太坊智能合約進行交互的最簡單方法是使用他們的。 在以太坊和其他區塊鏈中,仍有很多被證明的概念正在實施,開發人員在嘗試如何應對這些新概念。作為dInvest 系列文章一部分,我也在研究以太坊并嘗試在區塊鏈中實施對沖基金。在上一篇文章中...
摘要:一系列的類似的對象,如果無返回值時,可以省略。表示函數聲明自己不會改變狀態變量的值。表示函數可以接收,否則表示不能。哈哈,恭喜大家,到這里這里就完整的實現了一個基于以太坊去中心化網頁錢包。 本文首發于深入淺出區塊鏈社區原文鏈接:[使用 ethers.js 開發以太坊Web錢包4 - 發送Token (代幣)](https://learnblockchain.cn/20...,請讀者前往...
摘要:一系列的類似的對象,如果無返回值時,可以省略。表示函數聲明自己不會改變狀態變量的值。表示函數可以接收,否則表示不能。哈哈,恭喜大家,到這里這里就完整的實現了一個基于以太坊去中心化網頁錢包。 本文首發于深入淺出區塊鏈社區原文鏈接:[使用 ethers.js 開發以太坊Web錢包4 - 發送Token (代幣)](https://learnblockchain.cn/20...,請讀者前往...
摘要:是以太坊開發的個人區塊鏈,可用于部署合約,開發應用程序和運行測試。安裝是一個用于與以太坊交互的庫。啟動以太坊測試區塊鏈服務器要部署智能合約,我們應該啟動測試以太坊服務器。最后,你將在以太坊合約中設置調用用戶對象時獲得的值。 將數據存儲在數據庫中是任何軟件應用程序不可或缺的一部分。無論如何控制該數據庫都有一個該數據的主控。區塊鏈技術將數據存儲到區塊鏈網絡內的區塊中。因此,只要某個節點與網...
閱讀 3225·2021-11-08 13:21
閱讀 1202·2021-08-12 13:28
閱讀 1413·2019-08-30 14:23
閱讀 1935·2019-08-30 11:09
閱讀 850·2019-08-29 13:22
閱讀 2694·2019-08-29 13:12
閱讀 2557·2019-08-26 17:04
閱讀 2265·2019-08-26 13:22