成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

以太坊ABI介紹(二)

xiaoxiaozi / 3433人閱讀

摘要:上一篇我們講了中的參數(shù)含義以太坊介紹一,但是只有函數(shù)定義也是不行的,我們還需要調(diào)用,當(dāng)調(diào)用一個函數(shù)時也需要對該函數(shù)進(jìn)行編碼,這樣才能執(zhí)行,那么以太坊是如何生成可供調(diào)用的字節(jié)碼的。

上一篇我們講了ABI中的參數(shù)含義 以太坊ABI介紹(一),但是只有函數(shù)定義也是不行的,我們還需要調(diào)用,當(dāng)調(diào)用一個函數(shù)時也需要對該函數(shù)進(jìn)行編碼,這樣EVM才能執(zhí)行,那么以太坊是如何生成可供EVM調(diào)用的字節(jié)碼的。

生成的字節(jié)碼主要分兩部分:函數(shù)選擇器和參數(shù)編碼

函數(shù)選擇器

即函數(shù)編碼,對函數(shù)名稱+參數(shù)類型進(jìn)行sha3(keccak256)哈希運(yùn)算之后,取前4個字節(jié)

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,默認(rèn)端口7545,然后再命令行執(zhí)行以下命令

curl -X POST -i http://localhost:7545 --data "{
  "jsonrpc":"2.0",
  "method":"web3_sha3",
  "params":["set(uint256)"]
}"

返回結(jié)果:
{
  "jsonrpc": "2.0",
  "result": "0x60fe47b16ed402aae66ca03d2bfc51478ee897c26a1158669c7058d5f24898f4"
}

3、方法三:

const Web3 = require("web3")
const web3 = new Web3()
console.log(web3.sha3("set(uint256)"))
# 0x60fe47b16ed402aae66ca03d2bfc51478ee897c26a1158669c7058d5f24898f4

取前四個字節(jié)(一個字節(jié)=2個16進(jìn)制字符)即:0x60fe47b1

參數(shù)編碼

由于函數(shù)編碼占用了4個字節(jié),所以參數(shù)編碼從第五位開始

參數(shù)的編碼根據(jù)類型的不同,編碼方式也有所區(qū)別。主要分為固定類型和動態(tài)類型

1、固定類型

uint:M為integer類型代表M bits,0 < M <= 256 , M % 8 == 0,如uint32,uint8,uint256。

int:同上。同為從8到256位的無符號整數(shù)。

uint和int:整型,分別是uint256和int256的別名。注意: 函數(shù)參數(shù)類型是uint,轉(zhuǎn)sha3碼時要變成uint256。

address:地址,20個字節(jié),160bits。

bool:布爾類型,1個字節(jié),true:1,false:0。高位補(bǔ)0

bytes:固定大小的字節(jié)數(shù)組,0

2、動態(tài)類型

bytes:動態(tài)分配大小字節(jié)數(shù)組。不是一個值類型!

string:動態(tài)大小UTF8編碼的字符串,不是一個值類型!

T[] 某個類型的不定長數(shù)組

T[k] 某個類型的定長數(shù)組

編碼規(guī)則

固定類型的編碼就很簡單,直接將參數(shù)值轉(zhuǎn)成32字節(jié)長度的16進(jìn)制即可。但是有區(qū)別的是:不足32bytes時,數(shù)字類型,如果是正數(shù)高位補(bǔ)0,如果是負(fù)數(shù)高位補(bǔ)1,布爾類型高位補(bǔ)0,字節(jié)類型、字符串類型在低位補(bǔ)全
動態(tài)類型的編碼稍微復(fù)雜點,如果是固定長度就不需要計算偏移量,如果是不定長度就需要先計算偏移量,并在最后加上長度和具體值的編碼,詳細(xì)步驟下面會介紹

具體編碼過程

介紹的例子和官方文檔一樣,如果理解有偏差可以查看源文檔

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 {}
}
案例

案例一:
函數(shù):baz(bytes3[2] memory)
調(diào)用:baz(69, true)

0xcdcd77c0,在node中使用new Web3().sha3("baz(uint32,bool)")生成

const Web3 = require("web3")

const web3 = new Web3()
console.log(web3.sha3("f(uint256,uint32[],bytes10,bytes)"))

0x0000000000000000000000000000000000000000000000000000000000000045,十進(jìn)制69,轉(zhuǎn)成16進(jìn)制為45,因為是正數(shù),高位補(bǔ)0至32bytes

0x0000000000000000000000000000000000000000000000000000000000000001,bool類型,true=1false=0,高位補(bǔ)0

所以最終字符串為:(換行顯示是為了方便查看,實際是沒有換行)

0xcdcd77c0
0x0000000000000000000000000000000000000000000000000000000000000045
0x0000000000000000000000000000000000000000000000000000000000000001

返回:該函數(shù)返回的是true,output將會是

0x0000000000000000000000000000000000000000000000000000000000000000

案例二:
函數(shù):bar(bytes3[2] memory)
調(diào)用:bar(["abc", "def"])

0xfce353f6,在node中使用new Web3().sha3("bar(bytes3[2])")生成

固定長度不需要計算偏移量

0x6162630000000000000000000000000000000000000000000000000000000000,字符串abc轉(zhuǎn)成16進(jìn)制后為616263,低位補(bǔ)0,字符串轉(zhuǎn)16進(jìn)制可以使用這個工具

0x6465660000000000000000000000000000000000000000000000000000000000,同上

所以最終字符串為:(換行顯示是為了方便查看,實際是沒有換行)

0xfce353f6
0x6162630000000000000000000000000000000000000000000000000000000000
0x6465660000000000000000000000000000000000000000000000000000000000

案例三:
函數(shù):f(uint,uint32[],bytes10,bytes)
調(diào)用:f(0x123, [0x456, 0x789], "1234567890", "Hello, world!")

0x8be65246,在node中使用f(uint256,uint32[],bytes10,bytes)生成

0x00000000000000000000000000000000000000000000000000000000000001230x123對應(yīng)的16進(jìn)制,正數(shù)補(bǔ)全

0x0000000000000000000000000000000000000000000000000000000000000080,動態(tài)類型,計算偏移量。這個的偏移量是指實際存儲值的位置,由于這個函數(shù)有4個變量,那么實際存儲值的位置就是第五個32bytes位置,也就是說偏移量等于4*32bytes=128,轉(zhuǎn)成16進(jìn)制后就是對應(yīng)的值

0x3132333435363738393000000000000000000000000000000000000000000000,字符串1234567890轉(zhuǎn)成16進(jìn)制后為31323334353637383930,bytes類型,低位補(bǔ)全

0x00000000000000000000000000000000000000000000000000000000000000e0,動態(tài)類型,計算偏移量,這個偏移量就等于參數(shù)長度4*32bytes+前面的動態(tài)參數(shù)參數(shù)占有的長度(因為前面只有一個動態(tài)參數(shù),所以這個長度就是1*32bytes+2*32bytes,1*32bytes是第一個動態(tài)參數(shù)長度所占的bytes數(shù),2*32bytes是因為該函數(shù)中的第一個動態(tài)參數(shù)有2個值),那么具體的值就是 4*32bytes+(1*32bytes+2*32bytes)=7*32bytes=224,轉(zhuǎn)成16進(jìn)制就是e0,高位補(bǔ)全就是對應(yīng)的值

0x0000000000000000000000000000000000000000000000000000000000000002,第一個動態(tài)參數(shù)的長度,長度為2

0x0000000000000000000000000000000000000000000000000000000000000456,第一個動態(tài)參數(shù)中的第一個元素

0x0000000000000000000000000000000000000000000000000000000000000789,第一個動態(tài)參數(shù)中的第二個元素

0x000000000000000000000000000000000000000000000000000000000000000d,第二個動態(tài)參數(shù)的長度,長度為13

0x48656c6c6f2c20776f726c642100000000000000000000000000000000000000,第二個動態(tài)參數(shù)的值編碼

所以最終字符串為:(換行顯示是為了方便查看,實際是沒有換行)

0x8be65246
0000000000000000000000000000000000000000000000000000000000000123
0000000000000000000000000000000000000000000000000000000000000080
3132333435363738393000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000e0
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000456
0000000000000000000000000000000000000000000000000000000000000789
000000000000000000000000000000000000000000000000000000000000000d
48656c6c6f2c20776f726c642100000000000000000000000000000000000000

以上就是以太坊調(diào)用函數(shù)時生成字節(jié)碼的完整過程了!



歡迎訂閱「K叔區(qū)塊鏈」 - 專注于區(qū)塊鏈技術(shù)學(xué)習(xí)

博客地址:http://www.jouypub.com
簡書主頁:https://www.jianshu.com/u/756c9c8ae984
segmentfault主頁:https://segmentfault.com/blog/jouypub
騰訊云主頁:https://cloud.tencent.com/developer/column/72548

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/24343.html

相關(guān)文章

  • 以太ABI介紹(一)

    摘要:但是對于調(diào)用者來說,就需要知道合約有哪些方法,方法的參數(shù)是什么,返回值是什么,而這些信息就記錄在智能合約的中。 ABI是什么 ABI全稱 Application Binary Interface,字面意思是應(yīng)用程序二進(jìn)制接口,可以通俗的理解為合約的接口說明,當(dāng)合約被編譯后,它對應(yīng)的abi也就確定了。abi有點類似于程序中的接口文檔,描述了字段名稱、字段類型、方法名稱、參數(shù)名稱、參數(shù)類型...

    Cruise_Chan 評論0 收藏0
  • python使用web3py與以太智能合約交互

    摘要:合約規(guī)定了公共職能部門,以創(chuàng)造新的投資和撤資,這將成為對沖基金的主要職能。對沖基金的用戶通過其以太坊地址來識別,該地址相當(dāng)于公鑰。我發(fā)現(xiàn)與其他程序如程序的以太坊智能合約進(jìn)行交互的最簡單方法是使用他們的。 在以太坊和其他區(qū)塊鏈中,仍有很多被證明的概念正在實施,開發(fā)人員在嘗試如何應(yīng)對這些新概念。作為dInvest 系列文章一部分,我也在研究以太坊并嘗試在區(qū)塊鏈中實施對沖基金。在上一篇文章中...

    Joyven 評論0 收藏0
  • 以太錢包開發(fā)系列4 - 發(fā)送Token(代幣)

    摘要:一系列的類似的對象,如果無返回值時,可以省略。表示函數(shù)聲明自己不會改變狀態(tài)變量的值。表示函數(shù)可以接收,否則表示不能。哈哈,恭喜大家,到這里這里就完整的實現(xiàn)了一個基于以太坊去中心化網(wǎng)頁錢包。 本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接:[使用 ethers.js 開發(fā)以太坊Web錢包4 - 發(fā)送Token (代幣)](https://learnblockchain.cn/20...,請讀者前往...

    Honwhy 評論0 收藏0
  • 以太錢包開發(fā)系列4 - 發(fā)送Token(代幣)

    摘要:一系列的類似的對象,如果無返回值時,可以省略。表示函數(shù)聲明自己不會改變狀態(tài)變量的值。表示函數(shù)可以接收,否則表示不能。哈哈,恭喜大家,到這里這里就完整的實現(xiàn)了一個基于以太坊去中心化網(wǎng)頁錢包。 本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接:[使用 ethers.js 開發(fā)以太坊Web錢包4 - 發(fā)送Token (代幣)](https://learnblockchain.cn/20...,請讀者前往...

    HmyBmny 評論0 收藏0
  • python和flask框架開發(fā)以太智能合約

    摘要:是以太坊開發(fā)的個人區(qū)塊鏈,可用于部署合約,開發(fā)應(yīng)用程序和運(yùn)行測試。安裝是一個用于與以太坊交互的庫。啟動以太坊測試區(qū)塊鏈服務(wù)器要部署智能合約,我們應(yīng)該啟動測試以太坊服務(wù)器。最后,你將在以太坊合約中設(shè)置調(diào)用用戶對象時獲得的值。 將數(shù)據(jù)存儲在數(shù)據(jù)庫中是任何軟件應(yīng)用程序不可或缺的一部分。無論如何控制該數(shù)據(jù)庫都有一個該數(shù)據(jù)的主控。區(qū)塊鏈技術(shù)將數(shù)據(jù)存儲到區(qū)塊鏈網(wǎng)絡(luò)內(nèi)的區(qū)塊中。因此,只要某個節(jié)點與網(wǎng)...

    enrecul101 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<