parent
7afdc3de26
commit
aec6f8c9ec
@ -1,22 +1,16 @@ |
|||||||
'use strict' |
'use strict' |
||||||
|
var IntType = require('./Int') |
||||||
var util = require('./util') |
var util = require('./util') |
||||||
var ethutil = require('ethereumjs-util') |
|
||||||
var BN = require('ethereumjs-util').BN |
|
||||||
|
|
||||||
function Uint (storageBytes) { |
function Uint (storageBytes) { |
||||||
this.storageSlots = 1 |
this.storageSlots = 1 |
||||||
this.storageBytes = storageBytes |
this.storageBytes = storageBytes |
||||||
this.typeName = 'uint' |
this.typeName = 'uint' |
||||||
|
this.decodeInt = new IntType(storageBytes) |
||||||
} |
} |
||||||
|
|
||||||
Uint.prototype.decodeFromStorage = function (location, storageContent) { |
Uint.prototype.decodeFromStorage = function (location, storageContent) { |
||||||
var slot = ethutil.bufferToHex(ethutil.setLengthLeft(location.slot, 32)) |
return util.decodeInt(location, storageContent, this.storageBytes) |
||||||
if (!storageContent[slot]) { |
|
||||||
return '0' |
|
||||||
} |
|
||||||
var value = util.extractValue(storageContent[slot], this.storageBytes, location) |
|
||||||
var bigNumber = new BN(value.replace('0x', ''), 16) |
|
||||||
return bigNumber.toString(10) |
|
||||||
} |
} |
||||||
|
|
||||||
module.exports = Uint |
module.exports = Uint |
||||||
|
@ -1,13 +1,46 @@ |
|||||||
|
'use strict' |
||||||
|
var ethutil = require('ethereumjs-util') |
||||||
|
var BN = require('ethereumjs-util').BN |
||||||
|
|
||||||
module.exports = { |
module.exports = { |
||||||
extractValue: function (slotValue, storageBytes, location) { |
extractHexByteSlice: extractHexByteSlice, |
||||||
slotValue = slotValue.replace('0x', '') |
extractSlotValue: extractSlotValue, |
||||||
var offset = slotValue.length - 2 * location.offset - storageBytes / 4 |
decodeInt: decodeInt |
||||||
if (offset >= 0) { |
} |
||||||
return '0x' + slotValue.substr(offset, storageBytes / 4) |
|
||||||
} else if (offset + storageBytes > 0) { |
function decodeInt (location, storageContent, byteLength) { |
||||||
return '0x' + slotValue.substr(0, storageBytes / 4 + offset) |
var slotvalue = extractSlotValue(location.slot, storageContent) |
||||||
|
if (slotvalue === null) { |
||||||
|
return '0' |
||||||
|
} |
||||||
|
var value = extractHexByteSlice(slotvalue, byteLength, location.offset) |
||||||
|
var bigNumber = new BN(value, 16) |
||||||
|
bigNumber = bigNumber.fromTwos(8 * byteLength) |
||||||
|
return bigNumber.toString(10) |
||||||
|
} |
||||||
|
|
||||||
|
function extractSlotValue (slot, storageContent) { |
||||||
|
var hexSlot = ethutil.bufferToHex(slot) |
||||||
|
if (storageContent[hexSlot] !== undefined) { |
||||||
|
return storageContent[hexSlot] |
||||||
|
} else { |
||||||
|
hexSlot = ethutil.bufferToHex(ethutil.setLengthLeft(slot, 32)) |
||||||
|
if (storageContent[hexSlot]) { |
||||||
|
return storageContent[hexSlot] |
||||||
} else { |
} else { |
||||||
return '0x0' |
return null |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
|
function extractHexByteSlice (slotValue, byteLength, offsetFromLSB) { |
||||||
|
if (slotValue === undefined) { |
||||||
|
slotValue = '0' |
||||||
|
} |
||||||
|
slotValue = slotValue.replace('0x', '') |
||||||
|
if (slotValue.length < 64) { |
||||||
|
slotValue = (new Array(64 - slotValue.length + 1).join('0')) + slotValue |
||||||
|
} |
||||||
|
var offset = slotValue.length - 2 * offsetFromLSB - 2 * byteLength |
||||||
|
return slotValue.substr(offset, 2 * byteLength) |
||||||
|
} |
||||||
|
@ -0,0 +1,44 @@ |
|||||||
|
'use strict' |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
contract: ` |
||||||
|
contract intStorage { |
||||||
|
uint8 ui8 = 123; |
||||||
|
uint16 ui16 = 456; |
||||||
|
uint32 ui32 = 4356; |
||||||
|
uint64 ui64 = 3543543543; |
||||||
|
uint128 ui128 = 234567; |
||||||
|
uint256 ui256 = 234566666656; |
||||||
|
uint ui = 123545666; |
||||||
|
int8 i8 = -45; |
||||||
|
int16 i16 = -1234; |
||||||
|
int32 i32 = 3455; |
||||||
|
int64 i64 = -35566; |
||||||
|
int128 i128 = -444444; |
||||||
|
int256 i256 = 3434343; |
||||||
|
int i = -32432423423; |
||||||
|
int32 ishrink = 2; |
||||||
|
|
||||||
|
function intStorage () { |
||||||
|
} |
||||||
|
} |
||||||
|
`,
|
||||||
|
fullStorage: { |
||||||
|
'0x0000000000000000000000000000000000000000000000000000000000000000': '0x000000000000000000000000000003944700000000d3362ef70000110401c87b', |
||||||
|
'0x0000000000000000000000000000000000000000000000000000000000000001': '0x000000000000000000000000000000000000000000000000000000369d4349a0', |
||||||
|
'0x0000000000000000000000000000000000000000000000000000000000000002': '0x00000000000000000000000000000000000000000000000000000000075d2842', |
||||||
|
'0x0000000000000000000000000000000000000000000000000000000000000003': '0x00fffffffffffffffffffffffffff937e4ffffffffffff751200000d7ffb2ed3', |
||||||
|
'0x0000000000000000000000000000000000000000000000000000000000000004': '0x0000000000000000000000000000000000000000000000000000000000346767', |
||||||
|
'0x0000000000000000000000000000000000000000000000000000000000000005': '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffff872e07e01', |
||||||
|
'0x0000000000000000000000000000000000000000000000000000000000000006': '0x0000000000000000000000000000000000000000000000000000000000000002' |
||||||
|
}, |
||||||
|
shrinkedStorage: { |
||||||
|
'0x00': '0x03944700000000d3362ef70000110401c87b', |
||||||
|
'0x01': '0x369d4349a0', |
||||||
|
'0x02': '0x075d2842', |
||||||
|
'0x03': '0xfffffffffffffffffffffffffff937e4ffffffffffff751200000d7ffb2ed3', |
||||||
|
'0x04': '0x346767', |
||||||
|
'0x05': '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffff872e07e01', |
||||||
|
'0x06': '0x02' |
||||||
|
} |
||||||
|
} |
@ -1,155 +1,66 @@ |
|||||||
'use strict' |
'use strict' |
||||||
var tape = require('tape') |
var tape = require('tape') |
||||||
var compiler = require('solc') |
var compiler = require('solc') |
||||||
var VM = require('ethereumjs-vm') |
|
||||||
var Tx = require('ethereumjs-tx') |
|
||||||
var Block = require('ethereumjs-block') |
|
||||||
var ethUtil = require('ethereumjs-util') |
|
||||||
var BN = require('ethereumjs-util').BN |
|
||||||
var stateDecoder = require('../../src/index').solidity.stateDecoder |
var stateDecoder = require('../../src/index').solidity.stateDecoder |
||||||
|
|
||||||
tape('solidity', function (t) { |
tape('solidity', function (t) { |
||||||
t.test('storage decoder', function (st) { |
t.test('storage decoder', function (st) { |
||||||
var output = compiler.compile(intStorage, 0) |
testIntStorage(st) |
||||||
var vm = setupVM() |
|
||||||
var accountPrivateKey = new Buffer('3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511', 'hex') |
|
||||||
var address = ethUtil.privateToAddress(accountPrivateKey) |
|
||||||
vm.stateManager.putAccountBalance(address, 'f00000000000000001', function cb () {}) |
|
||||||
var tx = setupTransation(null, 0, output.contracts['intStorage'].bytecode) |
|
||||||
tx.sign(accountPrivateKey) |
|
||||||
executeTransaction(vm, tx, function (error, result) { |
|
||||||
if (error) { |
|
||||||
st.end(error) |
|
||||||
} else { |
|
||||||
vm.stateManager.dumpStorage(result.createdAddress, function (storage) { |
|
||||||
for (var k in storage) { |
|
||||||
if (storage[k].indexOf('a0') === 0) { |
|
||||||
storage[k] = storage[k].replace('a0', '0x') |
|
||||||
} else { |
|
||||||
storage[k] = '0x' + storage[k] |
|
||||||
} |
|
||||||
} |
|
||||||
var i = 0 |
|
||||||
while (i < 40) { |
|
||||||
var strK = ethUtil.bufferToHex(ethUtil.setLengthLeft(i, 32)) |
|
||||||
var sha3 = ethUtil.bufferToHex(ethUtil.sha3(strK)).replace('0x', '') |
|
||||||
if (storage[sha3]) { |
|
||||||
storage[strK] = storage[sha3] |
|
||||||
} |
|
||||||
i++ |
|
||||||
} |
|
||||||
var decodedState = stateDecoder.solidityState(storage, output.sources, 'intStorage') |
|
||||||
checkDecodedState(st, decodedState) |
|
||||||
st.end() |
|
||||||
}) |
|
||||||
} |
|
||||||
}) |
|
||||||
}) |
}) |
||||||
}) |
}) |
||||||
|
|
||||||
function executeTransaction (vm, tx, cb) { |
function testIntStorage (st) { |
||||||
var block = new Block({ |
var intStorage = require('./contracts/intStorage') |
||||||
header: { |
var output = compiler.compile(intStorage.contract, 0) |
||||||
timestamp: new Date().getTime() / 1000 | 0 |
var decoded = stateDecoder.solidityState(intStorage.fullStorage, output.sources, 'intStorage') |
||||||
}, |
|
||||||
transactions: [], |
|
||||||
uncleHeaders: [] |
|
||||||
}) |
|
||||||
|
|
||||||
vm.runTx({block: block, tx: tx, skipBalance: true, skipNonce: true}, function (error, result) { |
|
||||||
cb(error, result) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
function setupVM () { |
|
||||||
var vm = new VM({ |
|
||||||
enableHomestead: true, |
|
||||||
activatePrecompiles: true |
|
||||||
}) |
|
||||||
return vm |
|
||||||
} |
|
||||||
|
|
||||||
function setupTransation (to, value, data) { |
|
||||||
return new Tx({ |
|
||||||
nonce: new BN(0), |
|
||||||
gasPrice: new BN(1), |
|
||||||
gasLimit: new BN(3000000, 10), |
|
||||||
to: to, |
|
||||||
value: new BN(value, 10), |
|
||||||
data: new Buffer(data, 'hex') |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
var intStorage = ` |
|
||||||
contract intStorage { |
|
||||||
uint8 ui8; |
|
||||||
uint16 ui16; |
|
||||||
uint32 ui32; |
|
||||||
uint64 ui64; |
|
||||||
uint128 ui128; |
|
||||||
uint256 ui256; |
|
||||||
uint ui; |
|
||||||
int8 i8; |
|
||||||
int16 i16; |
|
||||||
int32 i32; |
|
||||||
int64 i64; |
|
||||||
int128 i128; |
|
||||||
int256 i256; |
|
||||||
int i; |
|
||||||
|
|
||||||
function intStorage () { |
|
||||||
ui8 = 0; |
|
||||||
ui16 = 0; |
|
||||||
ui32 = 0; |
|
||||||
ui64 = 0; |
|
||||||
ui128 = 2; |
|
||||||
ui256 = 0; |
|
||||||
ui = 0; |
|
||||||
i8 = 0; |
|
||||||
i16 = 0; |
|
||||||
i32 = 0; |
|
||||||
i64 = 0; |
|
||||||
i128 = 0; |
|
||||||
i256 = 0; |
|
||||||
i = 0; |
|
||||||
} |
|
||||||
} |
|
||||||
` |
|
||||||
|
|
||||||
function checkDecodedState (st, decoded) { |
|
||||||
console.log(JSON.stringify(decoded)) |
|
||||||
st.equal(decoded['ui8'], '123') |
st.equal(decoded['ui8'], '123') |
||||||
st.equal(decoded['ui16'], '354') |
st.equal(decoded['ui16'], '456') |
||||||
st.equal(decoded['ui32'], '1000') |
st.equal(decoded['ui32'], '4356') |
||||||
st.equal(decoded['ui64'], '23456') |
st.equal(decoded['ui64'], '3543543543') |
||||||
st.equal(decoded['ui128'], '234567') |
st.equal(decoded['ui128'], '234567') |
||||||
st.equal(decoded['ui256'], '1234566778') |
st.equal(decoded['ui256'], '234566666656') |
||||||
st.equal(decoded['ui'], '123545666') |
st.equal(decoded['ui'], '123545666') |
||||||
|
st.equal(decoded['i8'], '-45') |
||||||
|
st.equal(decoded['i16'], '-1234') |
||||||
|
st.equal(decoded['i32'], '3455') |
||||||
|
st.equal(decoded['i64'], '-35566') |
||||||
|
st.equal(decoded['i128'], '-444444') |
||||||
|
st.equal(decoded['i256'], '3434343') |
||||||
|
st.equal(decoded['i'], '-32432423423') |
||||||
|
st.equal(decoded['ishrink'], '2') |
||||||
|
|
||||||
st.equal(decoded['i8'], '45') |
decoded = stateDecoder.solidityState(intStorage.shrinkedStorage, output.sources, 'intStorage') |
||||||
st.equal(decoded['i16'], '1234') |
st.equal(decoded['ui8'], '123') |
||||||
|
st.equal(decoded['ui16'], '456') |
||||||
|
st.equal(decoded['ui32'], '4356') |
||||||
|
st.equal(decoded['ui64'], '3543543543') |
||||||
|
st.equal(decoded['ui128'], '234567') |
||||||
|
st.equal(decoded['ui256'], '234566666656') |
||||||
|
st.equal(decoded['ui'], '123545666') |
||||||
|
st.equal(decoded['i8'], '-45') |
||||||
|
st.equal(decoded['i16'], '-1234') |
||||||
st.equal(decoded['i32'], '3455') |
st.equal(decoded['i32'], '3455') |
||||||
st.equal(decoded['i64'], '-35566') |
st.equal(decoded['i64'], '-35566') |
||||||
st.equal(decoded['i128'], '-444444') |
st.equal(decoded['i128'], '-444444') |
||||||
st.equal(decoded['i256'], '3434343') |
st.equal(decoded['i256'], '3434343') |
||||||
st.equal(decoded['i'], '-32432423423') |
st.equal(decoded['i'], '-32432423423') |
||||||
} |
st.equal(decoded['ishrink'], '2') |
||||||
|
|
||||||
/* |
decoded = stateDecoder.solidityState({}, output.sources, 'intStorage') |
||||||
function intStorage () { |
st.equal(decoded['ui8'], '0') |
||||||
ui8 = 0; |
st.equal(decoded['ui16'], '0') |
||||||
ui16 = 0; |
st.equal(decoded['ui32'], '0') |
||||||
ui32 = 0; |
st.equal(decoded['ui64'], '0') |
||||||
ui64 = 0; |
st.equal(decoded['ui128'], '0') |
||||||
ui128 = 234567; |
st.equal(decoded['ui256'], '0') |
||||||
ui256 = 0; |
st.equal(decoded['ui'], '0') |
||||||
ui = 123545666; |
st.equal(decoded['i8'], '0') |
||||||
i8 = -45; |
st.equal(decoded['i16'], '0') |
||||||
i16 = -1234; |
st.equal(decoded['i32'], '0') |
||||||
i32 = 3455; |
st.equal(decoded['i64'], '0') |
||||||
i64 = -35566; |
st.equal(decoded['i128'], '0') |
||||||
i128 = -444444; |
st.equal(decoded['i256'], '0') |
||||||
i256 = 3434343; |
st.equal(decoded['i'], '0') |
||||||
i = -32432423423; |
st.equal(decoded['ishrink'], '0') |
||||||
} |
st.end() |
||||||
*/ |
} |
||||||
|
Loading…
Reference in new issue