aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm
diff options
context:
space:
mode:
authorWei-Ning Huang <w@cobinhood.com>2018-10-18 13:12:16 +0800
committerWei-Ning Huang <w@byzantine-lab.io>2019-06-12 17:23:39 +0800
commitdb1d03b5c2a6fbe370526dfaf283638773bab032 (patch)
tree305237d4831233521fe46f5901c34c8baccf9d4d /core/vm
parent12eb896a11eaf15712339ffa7eedf2b7c88fdfdd (diff)
downloadgo-tangerine-db1d03b5c2a6fbe370526dfaf283638773bab032.tar
go-tangerine-db1d03b5c2a6fbe370526dfaf283638773bab032.tar.gz
go-tangerine-db1d03b5c2a6fbe370526dfaf283638773bab032.tar.bz2
go-tangerine-db1d03b5c2a6fbe370526dfaf283638773bab032.tar.lz
go-tangerine-db1d03b5c2a6fbe370526dfaf283638773bab032.tar.xz
go-tangerine-db1d03b5c2a6fbe370526dfaf283638773bab032.tar.zst
go-tangerine-db1d03b5c2a6fbe370526dfaf283638773bab032.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')
-rw-r--r--core/vm/evm.go1
-rw-r--r--core/vm/instructions.go22
-rw-r--r--core/vm/jump_table.go6
-rw-r--r--core/vm/opcodes.go3
4 files changed, 32 insertions, 0 deletions
diff --git a/core/vm/evm.go b/core/vm/evm.go
index e22acb81c..be2dabcf5 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -90,6 +90,7 @@ type Context struct {
GasLimit uint64 // Provides information for GASLIMIT
BlockNumber *big.Int // Provides information for NUMBER
Time *big.Int // Provides information for TIME
+ Randomness []byte // Provides information for RAND
Difficulty *big.Int // Provides information for DIFFICULTY
}
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
diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go
index da158027a..608e34419 100644
--- a/core/vm/jump_table.go
+++ b/core/vm/jump_table.go
@@ -301,6 +301,12 @@ func newFrontierInstructionSet() [256]operation {
memorySize: memorySha3,
valid: true,
},
+ RAND: {
+ execute: opRand,
+ gasCost: constGasFunc(params.RandGas),
+ validateStack: makeStackFunc(0, 1),
+ valid: true,
+ },
ADDRESS: {
execute: opAddress,
gasCost: constGasFunc(GasQuickStep),
diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go
index 4349ffd29..8762d4b43 100644
--- a/core/vm/opcodes.go
+++ b/core/vm/opcodes.go
@@ -71,6 +71,7 @@ const (
SAR
SHA3 = 0x20
+ RAND = 0x2f
)
// 0x30 range - closure state.
@@ -251,6 +252,7 @@ var opCodeToString = map[OpCode]string{
// 0x20 range - crypto.
SHA3: "SHA3",
+ RAND: "RAND",
// 0x30 range - closure state.
ADDRESS: "ADDRESS",
@@ -420,6 +422,7 @@ var stringToOp = map[string]OpCode{
"ADDMOD": ADDMOD,
"MULMOD": MULMOD,
"SHA3": SHA3,
+ "RAND": RAND,
"ADDRESS": ADDRESS,
"BALANCE": BALANCE,
"ORIGIN": ORIGIN,