diff options
author | Wei-Ning Huang <w@cobinhood.com> | 2018-10-18 13:12:16 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@dexon.org> | 2019-04-09 21:32:50 +0800 |
commit | 6137f79f726e8ec6a282ee0ca4ed45c05020ed4c (patch) | |
tree | 9a9e5c3cc01e0a7c1898799562e13fabeaf608d5 /core/vm/instructions.go | |
parent | 1fa4415d48e4ed7ee0f75ed21e62847ea68d3a0f (diff) | |
download | dexon-6137f79f726e8ec6a282ee0ca4ed45c05020ed4c.tar.gz dexon-6137f79f726e8ec6a282ee0ca4ed45c05020ed4c.tar.zst dexon-6137f79f726e8ec6a282ee0ca4ed45c05020ed4c.zip |
core: vm: implement RAND opcode support
DEXON has a built-in on chain random oracle that allow one to retrieve a
random variable. Add a new opcode `RAND` to load the random variable
onto the stack.
Diffstat (limited to 'core/vm/instructions.go')
-rw-r--r-- | core/vm/instructions.go | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 349f407a2..de0fcaeb6 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -17,6 +17,7 @@ package vm import ( + "encoding/binary" "errors" "fmt" "math/big" @@ -24,6 +25,7 @@ import ( "github.com/dexon-foundation/dexon/common" "github.com/dexon-foundation/dexon/common/math" "github.com/dexon-foundation/dexon/core/types" + "github.com/dexon-foundation/dexon/crypto" "github.com/dexon-foundation/dexon/params" "golang.org/x/crypto/sha3" ) @@ -404,6 +406,26 @@ func opSha3(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory return nil, nil } +func opRand(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + evm := interpreter.evm + + nonce := evm.StateDB.GetNonce(contract.Caller()) + binaryNonce := make([]byte, binary.MaxVarintLen64) + binary.PutUvarint(binaryNonce, nonce) + + binaryGas := make([]byte, binary.MaxVarintLen64) + binary.PutUvarint(binaryGas, contract.Gas) + + hash := crypto.Keccak256( + evm.Randomness, + contract.Caller().Bytes(), + binaryNonce, + binaryGas) + + stack.push(interpreter.intPool.get().SetBytes(hash)) + return nil, nil +} + func opAddress(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { stack.push(contract.Address().Big()) return nil, nil |