To get a value from contract storage I used this geth code succesfully:
var contractAddress = '0x88e726de6cbadc47159c6ccd4f7868ae7a037730'
var index = '0000000000000000000000000000000000000000000000000000000000000001'
var key = '00000000000000000000000x8703f7b22fc5613497aee971e80480a46b226d3c'
var newKey = web3.sha3(key + index, {"encoding":"hex"})
newKey: "0x749bce6b8d0b50e46cbdb3872aefff8c0e7eee46cc4368971ef94ce14e0c3839"
console.log('TokenBalance: ' + web3.toDecimal(web3.eth.getStorageAt(contractAddress, newKey)))
TokenBalance: 1000000000
But, when trying to implement that same code on GoLang the hash newKey is different and everything fails.
Code at https://play.golang.org/p/6z8EX44A3QX
package main
import "fmt"
import "encoding/hex"
import "github.com/ethereum/go-ethereum/crypto"
func main() {
index := "0000000000000000000000000000000000000000000000000000000000000001"
key := "00000000000000000000000x8703f7b22fc5613497aee971e80480a46b226d3c"
// Crunching hash index for contract token balance at address 0x8703f7b22fc5613497aee971e80480a46b226d3c
// var newKey = sha3(key + index, {"encoding":"hex"})
var newKey = crypto.Keccak256([]byte(key + index))
fmt.Println("newKey: ", newKey)
fmt.Println(hex.Dump(newKey))
fmt.Println(hex.EncodeToString(newKey))
}
Output:
newKey: [236 52 49 125 144 82 178 166 201 55 151 68 129 249 89 25 207 168 159 24 108 235 39 14 14 14 169 233 76 45 248 192]
00000000 ec 34 31 7d 90 52 b2 a6 c9 37 97 44 81 f9 59 19 |.41}.R...7.D..Y.|
00000010 cf a8 9f 18 6c eb 27 0e 0e 0e a9 e9 4c 2d f8 c0 |....l.'.....L-..|
ec34317d9052b2a6c937974481f95919cfa89f186ceb270e0e0ea9e94c2df8c0
And when trying the same hash on nodeJs I get the same result as GoLang, but different from geth node:
$node
var util = require('ethereumjs-util');
var web3 = require("web3");
var index = '0000000000000000000000000000000000000000000000000000000000000001';
var key = '00000000000000000000000x8703f7b22fc5613497aee971e80480a46b226d3c';
var newKey1 = web3.utils.sha3(key + index, {"encoding":"hex"});
var newKey2 = util.keccak256(key+index);
console.log("NEWKEY 1", newKey1);
console.log("NEWKEY 2", "0x"+newKey2.toString('hex'));
Output:
NEWKEY 1 0xec34317d9052b2a6c937974481f95919cfa89f186ceb270e0e0ea9e94c2df8c0
NEWKEY 2 0xec34317d9052b2a6c937974481f95919cfa89f186ceb270e0e0ea9e94c2df8c0
And at go-ethereum source code I can confirm sha3 implementation is keccak256:
node\api.go(313):
// Sha3 applies the ethereum sha3 implementation on the input.
// It assumes the input is hex encoded.
func (s *PublicWeb3API) Sha3(input hexutil.Bytes) hexutil.Bytes {
return crypto.Keccak256(input)
}
The thing gets worst when trying to compute sha3/keccak256 using online tools:
At https://emn178.github.io/online-tools/keccak_256.html
input: 000000000000000000000000000000000000000000000000000000000000000100000000000000000000000x8703f7b22fc5613497aee971e80480a46b226d3c
output: fcc55d8cd146d5891583a2120b6546cc0e95a73b831ce3d165a6bc3bafe777e7
I guess I need to hash the ASCII string representation so trying first a conversion string to hex:
At http://string-functions.com/string-hex.aspx
string: 000000000000000000000000000000000000000000000000000000000000000100000000000000000000000x8703f7b22fc5613497aee971e80480a46b226d3c
hex: 3030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303130303030303030303030303030303030303030303030307838373033663762323266633536313334393761656539373165383034383061343662323236643363
And online hashing:
At https://emn178.github.io/online-tools/keccak_256.html
input: 3030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303130303030303030303030303030303030303030303030307838373033663762323266633536313334393761656539373165383034383061343662323236643363
output: 1bf2aa0bc8831bea8e5cfa462d8a825f0ed66b406b37fb63dd10ae6ebbf87ccc
Or padding with 0x:
input: 0x3030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303130303030303030303030303030303030303030303030307838373033663762323266633536313334393761656539373165383034383061343662323236643363
output: 6d09c345f835d959e3bcb83f0e6612d92041f901c041daf5448dbbf04c59af65
All three different outputs. How can it be? Thx for any hint!
By the way, I read this questions and answers but didn't found my answer: Which sha3 output is the correct one? Different hash values for keccak256 functions?