TMT观察网_独特视角观察TMT行业

如何讀取智能合約存儲區(qū)塊鏈

BUGX區(qū)塊安全 2018-08-10 18:25
分享到:
導讀

智能合約是區(qū)塊鏈技術(shù)的重要應用,所有部署在EVM上的合約都有專門用于存放狀態(tài)的存儲,本次區(qū)塊鏈安全團隊BUGX.IO給大家分享這個讀取思路。

一、前言

所有部署在EVM上的合約都有專門用于存放狀態(tài)(state)的存儲(storage)。這里是一個示例如何使用web3 js庫 `eth.getStorageAt()`方法讀取這個存儲。

二、示例代碼

示例合約代碼位于: ropsten. etherscan. io/ address/ 0xf1f5896ace3a78c347eb7eab503450bc93bd0c3b 

1.png

三、具體分析

從上面的示例代碼里,我們可以看到有11個狀態(tài)變量,現(xiàn)在我們逐個查看存儲中的狀態(tài)。

執(zhí)行:

npm install web3@ 0.20. 1 

node storage. js 

// storage.js

const Web3 = require('web3');

const web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io/0x88f9c0F375FDF741b1E218aC66f30408F5a55527")); // 你的錢包賬戶地址

let contractAddress = '0xf1f5896ace3a78c347eb7eab503450bc93bd0c3b';

let storage = '';

for (index = 0; index < 10; index ){

 storage = web3.eth.getStorageAt(contractAddress, index)

 console.log(`[${index}]` storage)

}

// result:

// [0] 0x000000000000000000000000000000000000000000000000000000000000000f

// [1] 0x00000000000000000000000059b92d9a0000000000000000000000000000429f

// [2] 0x0000000000000000000000000000000074657374310000000000000000000000

// [3] 0x7465737431323336000000000000000000000000000000000000000000000000

// [4] 0x6c65747320737472696e6720736f6d657468696e67000000000000000000002a

// [5] 0x0000000000000000000000000000000000000000000000000000000000000000

// [6] 0x0000000000000000000000000000000000000000000000000000000000000000

// [7] 0x0000000000000000000000000000000000000000000000000000000000000002

// [8] 0x0000000000000000000000000000000000000000000000000000000000000002

// [9] 0x0000000000000000000000000000000000000000000000000000000000000000

(1) Index 0?—?storeduint1

uint storeduint1 = 15;

解碼代碼如下:

bytecode = '0x000000000000000000000000000000000000000000000000000000000000000f';

console. log( 'DEC:'  web3. toDecimal( bytecode));

// DEC: 15 

(2)constuint

uint constant constuint = 16;

常值不存放在存儲中,僅在代碼中可用。

(3)index 1?—?investmentsLimit, investmentsDeadlineTimeStamp

在 Index 1 中合并了這兩個屬性以優(yōu)化存儲的使用。

uint128 investmentsLimit = 17055;

uint32 investmentsDeadlineTimeStamp = uint32( now);

解碼代碼如下:

bytecode = '0x00000000000000000000000059b92d9a';

console. log( 'DEC:'  web3. toDecimal( bytecode));

bytecode = '0x0000000000000000000000000000429f';

console. log( 'DEC:'  web3. toDecimal( bytecode));

// DEC: 1505308058 and 17055 

(4) index 2?—?string1

bytes16 string1 = 'test1';

解碼代碼如下:

bytecode = '0x0000000000000000000000000000000074657374310000000000000000000000';

console. log( 'ASCII:'  web3. toAscii( bytecode))

// ASCII: test1 

(5)index 3?—?string2

bytes32 string2 = 'test1236';

解碼代碼如下:

bytecode = '0x7465737431323336000000000000000000000000000000000000000000000000';

console. log( 'ASCII:'  web3. toAscii( bytecode));

// ASCII: test1236 

(6) index 4 — string3

string string3 = 'lets string something';

解碼代碼如下:

bytecode = '0x6c65747320737472696e6720736f6d657468696e67000000000000000000002a';

console. log( 'ASCII:'  web3. toAscii( bytecode));

// ASCII:lets string something* 

字節(jié)碼最后的符號 2a (dec 42) 用于表示存儲的字符串長度。

(7)index 5?—?uints1

mapping 類型的聲明形式為: `mapping(_KeyType => _ValueType)` 

示例中的代碼為:

uint[] uintarray;

address address1 = 0xbccc714d56bc0da0fd33d96d2a87b680dd6d0df6;

uints1[ address1] = 88;

mapping 類型有不同的索引形式,需要不同的讀取方式。本例中,KeyType為address,ValueType為uint,要讀取mapping值88,那你需要知道KeyType的值,即address1,否則是不可能讀取得到的。

解碼代碼如下:

index = '0000000000000000000000000000000000000000000000000000000000000005' 

key = '00000000000000000000000xbccc714d56bc0da0fd33d96d2a87b680dd6d0df6' 

let newKey = web3. sha3( key  index, { "encoding" : "hex"})

console. log( web3. eth. getStorageAt( contractAddress, newKey))

console. log( 'DEC: '  web3. toDecimal( web3. eth. getStorageAt( contractAddress, newKey)))

// result: 

// 0x0000000000000000000000000000000000000000000000000000000000000058 

// DEC: 88 

(8) index6?—?structs1

相關(guān)代碼:

struct DeviceData {

string deviceBrand;

string deviceYear;

string batteryWearLevel;

}

address address1 = 0xbccc714d56bc0da0fd33d96d2a87b680dd6d0df6;

var dev1 = DeviceData( 'deviceBrand', 'deviceYear', 'wearLevel');

structs1[ address1] = dev1;

另一種形式的mapping類型,通過增加newkey的方式去讀取里面的其它內(nèi)容。

需要先安裝bignumber模塊: `npm install --save bignumber.js` 

2.png

(9)index 7— uintarray

uint[] uintarray;

uintarray. push( 8000);

uintarray. push( 9000);

解碼代碼如下:

const Web3 = require('web3');

const web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io/0x88f9c0F375FDF741b1E218aC66f30408F5a55527")); // 你的錢包賬戶地址

let contractAddress = '0xf1f5896ace3a78c347eb7eab503450bc93bd0c3b';

var BigNumber = require('bignumber.js');

function increaseHexByOne(hex) {

 let x = new BigNumber(hex)

 let sum = x.plus(1)

 let result = '0x' sum.toString(16)

 return result

}

// 先讀取 item 數(shù)

index = "7"

console.log(web3.eth.getStorageAt(contractAddress, index))

// result:

// 0x0000000000000000000000000000000000000000000000000000000000000002

// This array has 2 items

// 將index轉(zhuǎn)為sha3散列,可以讀取數(shù)組的值

index = "0000000000000000000000000000000000000000000000000000000000000007"

let newKey = web3.sha3(index, {"encoding":"hex"})

console.log(web3.eth.getStorageAt(contractAddress, newKey))

console.log('DEC: '  web3.toDecimal(web3.eth.getStorageAt(contractAddress, newKey)))

// result:

// 0x0000000000000000000000000000000000000000000000000000000000001f40

// DEC: 8000

// 通過增加sha3散列值的形式讀取其它位置的值

newKey = increaseHexByOne(web3.sha3(index, {"encoding":"hex"}))

console.log(web3.eth.getStorageAt(contractAddress, newKey))

console.log('DEC: ' web3.toDecimal(web3.eth.getStorageAt(contractAddress, newKey)))

// result:

// 0x0000000000000000000000000000000000000000000000000000000000002328

// DEC: 9000

(10)index 8 — deviceDataArray

DeviceData[] deviceDataArray;

var dev1 = DeviceData( 'deviceBrand', 'deviceYear', 'wearLevel');

var dev2 = DeviceData( 'deviceBrand2', 'deviceYear2', 'wearLevel2');

deviceDataArray. push( dev1);

deviceDataArray. push( dev2);

解碼過程如下:

3.png

結(jié)果如下:

圖片1.png

index 代碼 web 讀取 address
分享到:

1.TMT觀察網(wǎng)遵循行業(yè)規(guī)范,任何轉(zhuǎn)載的稿件都會明確標注作者和來源;
2.TMT觀察網(wǎng)的原創(chuàng)文章,請轉(zhuǎn)載時務必注明文章作者和"來源:TMT觀察網(wǎng)",不尊重原創(chuàng)的行為TMT觀察網(wǎng)或?qū)⒆肪控熑危?br> 3.作者投稿可能會經(jīng)TMT觀察網(wǎng)編輯修改或補充。


專題報道

主站蜘蛛池模板: 轴承振动测量仪电箱-轴承测振动仪器-测试仪厂家-杭州居易电气 | 南昌旅行社_南昌国际旅行社_南昌国旅在线 | 智慧钢琴-电钢琴-便携钢琴-数码钢琴-深圳市特伦斯乐器有限公司 | EDLC超级法拉电容器_LIC锂离子超级电容_超级电容模组_软包单体电容电池_轴向薄膜电力电容器_深圳佳名兴电容有限公司_JMX专注中高端品牌电容生产厂家 | 成都热收缩包装机_袖口式膜包机_高速塑封机价格_全自动封切机器_大型套膜机厂家 | 纯化水设备-EDI-制药-实验室-二级反渗透-高纯水|超纯水设备 | 宽带办理,电信宽带,移动宽带,联通宽带,电信宽带办理,移动宽带办理,联通宽带办理 | 合肥花魁情感婚姻咨询中心_挽回爱情_修复婚姻_恋爱指南 | VOC检测仪-甲醛检测仪-气体报警器-气体检测仪厂家-深恒安科技有限公司 | 电动不锈钢套筒阀-球面偏置气动钟阀-三通换向阀止回阀-永嘉鸿宇阀门有限公司 | 丹佛斯变频器-Danfoss战略代理经销商-上海津信变频器有限公司 | 澳威全屋定制官网|极简衣柜十大品牌|衣柜加盟代理|全屋定制招商 百度爱采购运营研究社社群-店铺托管-爱采购代运营-良言多米网络公司 | 家乐事净水器官网-净水器厂家「官方」 | 一体式钢筋扫描仪-楼板测厚仪-裂缝检测仪-泰仕特(北京) | 浴室柜-浴室镜厂家-YINAISI · 意大利设计师品牌 | 咿耐斯 |-浙江台州市丰源卫浴有限公司 | 北京森语科技有限公司-模型制作专家-展览展示-沙盘模型设计制作-多媒体模型软硬件开发-三维地理信息交互沙盘 | 医养体检包_公卫随访箱_慢病随访包_家签随访包_随访一体机-济南易享医疗科技有限公司 | 坏男孩影院-提供最新电影_动漫_综艺_电视剧_迅雷免费电影最新观看 | 河南15年专业网站建设制作设计,做网站就找郑州启凡网络公司 | 超声波清洗机_大型超声波清洗机_工业超声波清洗设备-洁盟清洗设备 | 超声波分散机-均质机-萃取仪-超声波涂料分散设备-杭州精浩 | 中药超微粉碎机(中药细胞级微粉碎)-百科| 淘气堡_室内儿童乐园_户外无动力儿童游乐设备-高乐迪(北京) | 27PR跨境电商导航 | 专注外贸跨境电商 | 酒店品牌设计-酒店vi设计-酒店标识设计【国际级】VI策划公司 | 电动葫芦|手拉葫芦|环链电动葫芦|微型电动葫芦-北京市凌鹰起重机械有限公司 | 东莞喷砂机-喷砂机-喷砂机配件-喷砂器材-喷砂加工-东莞市协帆喷砂机械设备有限公司 | 北京三友信电子科技有限公司-ETC高速自动栏杆机|ETC机柜|激光车辆轮廓测量仪|嵌入式车道控制器 | 不锈钢闸阀_球阀_蝶阀_止回阀_调节阀_截止阀-可拉伐阀门(上海)有限公司 | 杭州门窗厂家_阳光房_包阳台安装电话-杭州窗猫铝合金门窗 | 北京模型公司-军事模型-工业模型制作-北京百艺模型沙盘公司 | 酒精检测棒,数显温湿度计,酒安酒精测试仪,酒精检测仪,呼气式酒精检测仪-郑州欧诺仪器有限公司 | 工控机-工业平板电脑-研华工控机-研越无风扇嵌入式box工控机 | 单机除尘器 骨架-脉冲除尘器设备生产厂家-润天环保设备 | ASA膜,ASA共挤料,篷布色母料-青岛未来化学有限公司 | 气动机械手-搬运机械手-气动助力机械手-山东精瑞自动化设备有限公司 | 钢衬四氟管道_钢衬四氟直管_聚四氟乙烯衬里管件_聚四氟乙烯衬里管道-沧州汇霖管道科技有限公司 | 悬浮拼装地板_幼儿园_篮球场_悬浮拼接地板-山东悬浮拼装地板厂家 | 上海防爆真空干燥箱-上海防爆冷库-上海防爆冷柜?-上海浦下防爆设备厂家? | X光检测仪_食品金属异物检测机_X射线检测设备_微现检测 | 欧景装饰设计工程有限公司-无锡欧景装饰官网 |