diff --git a/contracts/smcReader.go b/contracts/smcReader.go index e5497fd1bf..0363b1ac97 100644 --- a/contracts/smcReader.go +++ b/contracts/smcReader.go @@ -3,13 +3,11 @@ package contracts import ( "fmt" "strings" - "math/big" "time" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/contracts/blocksigner/contract" "github.com/ethereum/go-ethereum/core/types" ) @@ -35,25 +33,28 @@ func GetSigners(statedb *state.StateDB, parsed abi.ABI, block *types.Block) ([]c } func getSigners(parsed abi.ABI, statedb *state.StateDB, address common.Address, methodName string, input ...common.Hash) ([]common.Address) { - keys := getKeyStorage(statedb, address, parsed, methodName, input...) + keys := getKeys(statedb, address, parsed, methodName, input...) rets := []common.Address{} ret := common.Address{} for _, key := range keys { value := statedb.GetState(address, key) method := parsed.Methods[methodName] switch method.Outputs[0].Type.T { - case abi.StringTy: - //do nothing - output can't be string in this method - //ret = string(value.Bytes()) + case abi.AddressTy: + ret = common.BytesToAddress(value.Bytes()) default: - parsed.Unpack(&ret, methodName, value.Bytes()) - rets = append(rets, ret) + err := parsed.Unpack(&ret, methodName, value.Bytes()) + if err != nil { + fmt.Printf("err: %v\n", err) + } + //ret = common.BytesToAddress(value.Bytes()) } + rets = append(rets, ret) } return rets } -func getKeyStorage(statedb *state.StateDB, address common.Address, parsed abi.ABI, methodName string, input ...common.Hash) ([]common.Hash) { +func getKeys(statedb *state.StateDB, address common.Address, parsed abi.ABI, methodName string, input ...common.Hash) ([]common.Hash) { method, ok := parsed.Methods[methodName] slot := slotBlockSignerMapping[methodName] keys := []common.Hash{} @@ -61,36 +62,17 @@ func getKeyStorage(statedb *state.StateDB, address common.Address, parsed abi.AB // do not support function call if ok && len(method.Inputs) <= 1 || len(method.Outputs) == 1 { if len(method.Inputs) == 0 { - keys = append(keys, getKey(slot)) + keys = append(keys, getLocSimpleVariable(slot)) } else { // support first input - keyArrSlot := mapLocAtKey(input[0], slot) + keyArrSlot := getLocMappingAtKey(input[0], slot) arrSlot := statedb.GetState(address, keyArrSlot) arrLength := arrSlot.Big().Uint64() for i := uint64(0); i < arrLength; i++ { - valueHash := arrDynamicLocAtElement(keyArrSlot, i, 1) + valueHash := getLocDynamicArrAtElement(keyArrSlot, i, 1) keys = append(keys, valueHash) } } } return keys -} - -func getKey(slot uint64) common.Hash { - updatedKey := common.BigToHash(new(big.Int).SetUint64(slot)) - return updatedKey -} - -func mapLocAtKey(key common.Hash, slot uint64) common.Hash { - slotHash := common.BigToHash(new(big.Int).SetUint64(slot)) - updatedKey := crypto.Keccak256Hash(key.Bytes(), slotHash.Bytes()) - return updatedKey -} - -func arrDynamicLocAtElement(slotHash common.Hash, index uint64, elementSize uint64) common.Hash { - slotKecBig := crypto.Keccak256Hash(slotHash.Bytes()).Big() - //arrBig = slotKecBig + index * elementSize - arrBig := slotKecBig.Add(slotKecBig, new(big.Int).SetUint64(index * elementSize)) - arrHash := common.BigToHash(arrBig) - return arrHash } \ No newline at end of file diff --git a/contracts/smcUtils.go b/contracts/smcUtils.go new file mode 100644 index 0000000000..3aeefe8962 --- /dev/null +++ b/contracts/smcUtils.go @@ -0,0 +1,30 @@ +package contracts + +import ( + "math/big" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +func getLocSimpleVariable (slot uint64) common.Hash { + slotHash := common.BigToHash(new(big.Int).SetUint64(slot)) + return slotHash +} + +func getLocMappingAtKey (key common.Hash, slot uint64) common.Hash { + slotHash := common.BigToHash(new(big.Int).SetUint64(slot)) + return crypto.Keccak256Hash(key.Bytes(), slotHash.Bytes()) +} + +func getLocDynamicArrAtElement (slotHash common.Hash, index uint64, elementSize uint64) common.Hash { + slotKecBig := crypto.Keccak256Hash(slotHash.Bytes()).Big() + //arrBig = slotKecBig + index * elementSize + arrBig := slotKecBig.Add(slotKecBig, new(big.Int).SetUint64(index * elementSize)) + return common.BigToHash(arrBig) +} + +func getLocFixedArrAtElement (slot uint64, index uint64, elementSize uint64) common.Hash { + slotBig := new(big.Int).SetUint64(slot) + arrBig := slotBig.Add(slotBig, new(big.Int).SetUint64(index * elementSize)) + return common.BigToHash(arrBig) +} \ No newline at end of file