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@dexon.org>2018-12-19 20:54:27 +0800
commit517e0a104d7de13204659fa24da055bcb17f80a2 (patch)
treef6df8f71f09b233dc3b716a641081122a2d6d487 /core/vm
parent834ed1db5b5a7d24dacf58084782f68113171075 (diff)
downloaddexon-517e0a104d7de13204659fa24da055bcb17f80a2.tar
dexon-517e0a104d7de13204659fa24da055bcb17f80a2.tar.gz
dexon-517e0a104d7de13204659fa24da055bcb17f80a2.tar.bz2
dexon-517e0a104d7de13204659fa24da055bcb17f80a2.tar.lz
dexon-517e0a104d7de13204659fa24da055bcb17f80a2.tar.xz
dexon-517e0a104d7de13204659fa24da055bcb17f80a2.tar.zst
dexon-517e0a104d7de13204659fa24da055bcb17f80a2.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 8a850de9d..2ffbdb542 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/crypto/sha3"
"github.com/dexon-foundation/dexon/params"
)
@@ -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,