aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm
diff options
context:
space:
mode:
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,