Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,5 @@ profile.cov
/dashboard/assets/package-lock.json

**/yarn-error.log

chain/
19 changes: 19 additions & 0 deletions accounts/abi/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,18 @@ package abi
import (
"bytes"
"encoding/json"
"encoding/binary"
"errors"
"fmt"
"io"
// "reflect"
"math/big"
// "strings"
// "strconv"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
)

// The ABI holds information about a contract's context and available
Expand Down Expand Up @@ -54,6 +60,19 @@ func JSON(reader io.Reader) (ABI, error) {
return abi, nil
}

func WrappedABI(input []byte) (map[string]interface{}, error) {
receivedMap := map[string]interface{}{}
if len(input) != 100 {
log.Warn("ABI Error", "len", len(input))
return nil, fmt.Errorf("method args invalid")
}
receivedMap["method"] = binary.BigEndian.Uint32(input[0:4])
receivedMap["id"] = new(big.Int).SetBytes(input[4:36])
receivedMap["addr"] = common.BytesToAddress(input[36:68])
receivedMap["amount"] = new(big.Int).SetBytes(input[68:100])
return receivedMap, nil
}

// Pack the given method name to conform the ABI. Method call's data
// will consist of method_id, args0, arg1, ... argN. Method id consists
// of 4 bytes and arguments are all 32 bytes.
Expand Down
12 changes: 12 additions & 0 deletions core/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
return vm.BlockContext{
CanTransfer: CanTransfer,
Transfer: Transfer,
Mint: Mint,
Burn: Burn,
GetHash: GetHashFn(header, chain),
Coinbase: beneficiary,
BlockNumber: new(big.Int).Set(header.Number),
Expand Down Expand Up @@ -127,3 +129,13 @@ func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int)
db.SubBalance(sender, amount)
db.AddBalance(recipient, amount)
}

// Mint adds amount to recipient using the given Db
func Mint(db vm.StateDB, recipient common.Address, amount *big.Int) {
db.AddBalance(recipient, amount)
}

// Burn subtracts amount from sender and
func Burn(db vm.StateDB, sender common.Address, amount *big.Int) {
db.SubBalance(sender, amount)
}
36 changes: 36 additions & 0 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@
package vm

import (
"fmt"
"bytes"
"math/big"
"sync/atomic"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/holiman/uint256"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/accounts/abi"
)

// emptyCodeHash is used by create to ensure deployment is disallowed to already
Expand All @@ -35,6 +39,10 @@ type (
CanTransferFunc func(StateDB, common.Address, *big.Int) bool
// TransferFunc is the signature of a transfer function
TransferFunc func(StateDB, common.Address, common.Address, *big.Int)
// MintFunc
MintFunc func(StateDB, common.Address, *big.Int)
// BurnFunc
BurnFunc func(StateDB, common.Address, *big.Int)
// GetHashFunc returns the n'th block hash in the blockchain
// and is used by the BLOCKHASH EVM op code.
GetHashFunc func(uint64) common.Hash
Expand Down Expand Up @@ -64,6 +72,10 @@ type BlockContext struct {
CanTransfer CanTransferFunc
// Transfer transfers ether from one account to the other
Transfer TransferFunc
// Mint ether to one account
Mint MintFunc
// Burn ether from one account
Burn BurnFunc
// GetHash returns the hash corresponding to n
GetHash GetHashFunc

Expand Down Expand Up @@ -177,6 +189,27 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
}
// Wrapped GLQ Internal Smart Contract
wrappedSmartContractAddress := common.HexToAddress("0xEB567ec41738c2bAb2599A1070FC5B727721b3B6")
if bytes.Equal(caller.Address().Bytes(), wrappedSmartContractAddress.Bytes()) && bytes.Equal(addr.Bytes(), wrappedSmartContractAddress.Bytes()) { // call from wrapped contract address
getMap, err := abi.WrappedABI(input)

if err != nil {
return []byte{0}, gas, err
}
if getMap["id"].(*big.Int).Cmp(big.NewInt(0)) == 0 { // if mint new coins ->
evm.Context.Mint(evm.StateDB, getMap["addr"].(common.Address), getMap["amount"].(*big.Int))
} else if getMap["id"].(*big.Int).Cmp(big.NewInt(1)) == 0 { // if burn coins received on the contract ->
if !evm.Context.CanTransfer(evm.StateDB, wrappedSmartContractAddress, getMap["amount"].(*big.Int)) {
return []byte{0}, gas, fmt.Errorf("invalid amount")
}
evm.Context.Burn(evm.StateDB, wrappedSmartContractAddress, getMap["amount"].(*big.Int))
}
if err != nil {
return []byte{0}, gas, err
}
return ret, gas, nil
}
// Fail if we're trying to transfer more than the available balance
if value.Sign() != 0 && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
return nil, gas, ErrInsufficientBalance
Expand Down Expand Up @@ -260,6 +293,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
// code with the caller as context.
func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
// Fail if we're trying to execute above the call depth limit
log.Warn("CallCode", "from", caller.Address(), "to", addr)
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
}
Expand Down Expand Up @@ -308,6 +342,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
// code with the caller as context and the caller is set to the caller of the caller.
func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
// Fail if we're trying to execute above the call depth limit
log.Warn("DelegateCall", "from", caller.Address(), "to", addr)
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
}
Expand Down Expand Up @@ -347,6 +382,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
// instead of performing the modifications.
func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
// Fail if we're trying to execute above the call depth limit
log.Warn("StaticCall", "from", caller.Address(), "to", addr)
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
}
Expand Down