fix uint, int

pull/7/head
yann300 8 years ago
parent 7afdc3de26
commit aec6f8c9ec
  1. 19
      src/solidity/types/Int.js
  2. 12
      src/solidity/types/Uint.js
  3. 49
      src/solidity/types/util.js
  4. 44
      test/solidity/contracts/intStorage.js
  5. 181
      test/solidity/storageDecoder.js

@ -1,7 +1,5 @@
'use strict' 'use strict'
var util = require('./util') var util = require('./util')
var BN = require('ethereumjs-util').BN
var ethutil = require('ethereumjs-util')
function Int (storageBytes) { function Int (storageBytes) {
this.storageSlots = 1 this.storageSlots = 1
@ -10,22 +8,7 @@ function Int (storageBytes) {
} }
Int.prototype.decodeFromStorage = function (location, storageContent) { Int.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)
if (isNegative(bigNumber, this.storageBytes)) {
return ethutil.fromSigned(ethutil.toUnsigned(bigNumber)).toString(10)
} else {
return bigNumber.toString(10)
}
} }
module.exports = Int module.exports = Int
function isNegative (value, storageBytes) {
var binary = value.toString(2)
return binary.length < storageBytes ? false : binary[0] === '1'
}

@ -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…
Cancel
Save