github.com/halybang/go-ethereum@v1.0.5-0.20180325041310-3b262bc1367c/core/vm/contracts.go (about)

     1  // Copyright 2018 Wanchain Foundation Ltd
     2  // Copyright 2014 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package vm
    19  
    20  import (
    21  	"crypto/sha256"
    22  	"errors"
    23  	"math/big"
    24  
    25  	"crypto/ecdsa"
    26  	"strings"
    27  
    28  	"github.com/wanchain/go-wanchain/accounts/abi"
    29  	"github.com/wanchain/go-wanchain/accounts/keystore"
    30  	"github.com/wanchain/go-wanchain/common"
    31  	"github.com/wanchain/go-wanchain/common/hexutil"
    32  	"github.com/wanchain/go-wanchain/common/math"
    33  	"github.com/wanchain/go-wanchain/core/types"
    34  	"github.com/wanchain/go-wanchain/crypto"
    35  	"github.com/wanchain/go-wanchain/crypto/bn256"
    36  	"github.com/wanchain/go-wanchain/log"
    37  	"github.com/wanchain/go-wanchain/params"
    38  	"golang.org/x/crypto/ripemd160"
    39  	"fmt"
    40  )
    41  
    42  // RunPrecompiledContract runs and evaluates the output of a precompiled contract.
    43  func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contract, evm *EVM) (ret []byte, err error) {
    44  	gas := p.RequiredGas(input)
    45  	if contract.UseGas(gas) {
    46  		return p.Run(input, contract, evm)
    47  	}
    48  	return nil, ErrOutOfGas
    49  }
    50  
    51  // ECRECOVER implemented as a native contract.
    52  type ecrecover struct{}
    53  
    54  func (c *ecrecover) RequiredGas(input []byte) uint64 {
    55  	return params.EcrecoverGas
    56  }
    57  
    58  func (c *ecrecover) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) {
    59  	const ecRecoverInputLength = 128
    60  
    61  	input = common.RightPadBytes(input, ecRecoverInputLength)
    62  	// "input" is (hash, v, r, s), each 32 bytes
    63  	// but for ecrecover we want (r, s, v)
    64  
    65  	r := new(big.Int).SetBytes(input[64:96])
    66  	s := new(big.Int).SetBytes(input[96:128])
    67  	v := input[63] - 27
    68  
    69  	// tighter sig s values input homestead only apply to tx sigs
    70  	if !allZero(input[32:63]) || !crypto.ValidateSignatureValues(v, r, s, false) {
    71  		return nil, nil
    72  	}
    73  	// v needs to be at the end for libsecp256k1
    74  	pubKey, err := crypto.Ecrecover(input[:32], append(input[64:128], v))
    75  	// make sure the public key is a valid one
    76  	if err != nil {
    77  		return nil, nil
    78  	}
    79  
    80  	// the first byte of pubkey is bitcoin heritage
    81  	return common.LeftPadBytes(crypto.Keccak256(pubKey[1:])[12:], 32), nil
    82  }
    83  
    84  func (c *ecrecover) ValidTx(stateDB StateDB, signer types.Signer, tx *types.Transaction) error {
    85  	return nil
    86  }
    87  
    88  // SHA256 implemented as a native contract.
    89  type sha256hash struct{}
    90  
    91  // RequiredGas returns the gas required to execute the pre-compiled contract.
    92  //
    93  // This method does not require any overflow checking as the input size gas costs
    94  // required for anything significant is so high it's impossible to pay for.
    95  func (c *sha256hash) RequiredGas(input []byte) uint64 {
    96  	return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas
    97  }
    98  func (c *sha256hash) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) {
    99  	h := sha256.Sum256(input)
   100  	return h[:], nil
   101  }
   102  
   103  func (c *sha256hash) ValidTx(stateDB StateDB, signer types.Signer, tx *types.Transaction) error {
   104  	return nil
   105  }
   106  
   107  // RIPMED160 implemented as a native contract.
   108  type ripemd160hash struct{}
   109  
   110  // RequiredGas returns the gas required to execute the pre-compiled contract.
   111  //
   112  // This method does not require any overflow checking as the input size gas costs
   113  // required for anything significant is so high it's impossible to pay for.
   114  func (c *ripemd160hash) RequiredGas(input []byte) uint64 {
   115  	return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas
   116  }
   117  func (c *ripemd160hash) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) {
   118  	ripemd := ripemd160.New()
   119  	ripemd.Write(input)
   120  	return common.LeftPadBytes(ripemd.Sum(nil), 32), nil
   121  }
   122  
   123  func (c *ripemd160hash) ValidTx(stateDB StateDB, signer types.Signer, tx *types.Transaction) error {
   124  	return nil
   125  }
   126  
   127  // data copy implemented as a native contract.
   128  type dataCopy struct{}
   129  
   130  // RequiredGas returns the gas required to execute the pre-compiled contract.
   131  //
   132  // This method does not require any overflow checking as the input size gas costs
   133  // required for anything significant is so high it's impossible to pay for.
   134  func (c *dataCopy) RequiredGas(input []byte) uint64 {
   135  	return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas
   136  }
   137  func (c *dataCopy) Run(in []byte, contract *Contract, evm *EVM) ([]byte, error) {
   138  	return in, nil
   139  }
   140  
   141  func (c *dataCopy) ValidTx(stateDB StateDB, signer types.Signer, tx *types.Transaction) error {
   142  	return nil
   143  }
   144  
   145  // bigModExp implements a native big integer exponential modular operation.
   146  type bigModExp struct{}
   147  
   148  var (
   149  	big1      = big.NewInt(1)
   150  	big4      = big.NewInt(4)
   151  	big8      = big.NewInt(8)
   152  	big16     = big.NewInt(16)
   153  	big32     = big.NewInt(32)
   154  	big64     = big.NewInt(64)
   155  	big96     = big.NewInt(96)
   156  	big480    = big.NewInt(480)
   157  	big1024   = big.NewInt(1024)
   158  	big3072   = big.NewInt(3072)
   159  	big199680 = big.NewInt(199680)
   160  )
   161  
   162  // RequiredGas returns the gas required to execute the pre-compiled contract.
   163  func (c *bigModExp) RequiredGas(input []byte) uint64 {
   164  	var (
   165  		baseLen = new(big.Int).SetBytes(getData(input, 0, 32))
   166  		expLen  = new(big.Int).SetBytes(getData(input, 32, 32))
   167  		modLen  = new(big.Int).SetBytes(getData(input, 64, 32))
   168  	)
   169  	if len(input) > 96 {
   170  		input = input[96:]
   171  	} else {
   172  		input = input[:0]
   173  	}
   174  	// Retrieve the head 32 bytes of exp for the adjusted exponent length
   175  	var expHead *big.Int
   176  	if big.NewInt(int64(len(input))).Cmp(baseLen) <= 0 {
   177  		expHead = new(big.Int)
   178  	} else {
   179  		if expLen.Cmp(big32) > 0 {
   180  			expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), 32))
   181  		} else {
   182  			expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), expLen.Uint64()))
   183  		}
   184  	}
   185  	// Calculate the adjusted exponent length
   186  	var msb int
   187  	if bitlen := expHead.BitLen(); bitlen > 0 {
   188  		msb = bitlen - 1
   189  	}
   190  	adjExpLen := new(big.Int)
   191  	if expLen.Cmp(big32) > 0 {
   192  		adjExpLen.Sub(expLen, big32)
   193  		adjExpLen.Mul(big8, adjExpLen)
   194  	}
   195  	adjExpLen.Add(adjExpLen, big.NewInt(int64(msb)))
   196  
   197  	// Calculate the gas cost of the operation
   198  	gas := new(big.Int).Set(math.BigMax(modLen, baseLen))
   199  	switch {
   200  	case gas.Cmp(big64) <= 0:
   201  		gas.Mul(gas, gas)
   202  	case gas.Cmp(big1024) <= 0:
   203  		gas = new(big.Int).Add(
   204  			new(big.Int).Div(new(big.Int).Mul(gas, gas), big4),
   205  			new(big.Int).Sub(new(big.Int).Mul(big96, gas), big3072),
   206  		)
   207  	default:
   208  		gas = new(big.Int).Add(
   209  			new(big.Int).Div(new(big.Int).Mul(gas, gas), big16),
   210  			new(big.Int).Sub(new(big.Int).Mul(big480, gas), big199680),
   211  		)
   212  	}
   213  	gas.Mul(gas, math.BigMax(adjExpLen, big1))
   214  	gas.Div(gas, new(big.Int).SetUint64(params.ModExpQuadCoeffDiv))
   215  
   216  	if gas.BitLen() > 64 {
   217  		return math.MaxUint64
   218  	}
   219  	return gas.Uint64()
   220  }
   221  
   222  func (c *bigModExp) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) {
   223  	var (
   224  		baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64()
   225  		expLen  = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64()
   226  		modLen  = new(big.Int).SetBytes(getData(input, 64, 32)).Uint64()
   227  	)
   228  	if len(input) > 96 {
   229  		input = input[96:]
   230  	} else {
   231  		input = input[:0]
   232  	}
   233  	// Handle a special case when both the base and mod length is zero
   234  	if baseLen == 0 && modLen == 0 {
   235  		return []byte{}, nil
   236  	}
   237  	// Retrieve the operands and execute the exponentiation
   238  	var (
   239  		base = new(big.Int).SetBytes(getData(input, 0, baseLen))
   240  		exp  = new(big.Int).SetBytes(getData(input, baseLen, expLen))
   241  		mod  = new(big.Int).SetBytes(getData(input, baseLen+expLen, modLen))
   242  	)
   243  	if mod.BitLen() == 0 {
   244  		// Modulo 0 is undefined, return zero
   245  		return common.LeftPadBytes([]byte{}, int(modLen)), nil
   246  	}
   247  	return common.LeftPadBytes(base.Exp(base, exp, mod).Bytes(), int(modLen)), nil
   248  }
   249  
   250  func (c *bigModExp) ValidTx(stateDB StateDB, signer types.Signer, tx *types.Transaction) error {
   251  	return nil
   252  }
   253  
   254  var (
   255  	// errNotOnCurve is returned if a point being unmarshalled as a bn256 elliptic
   256  	// curve point is not on the curve.
   257  	errNotOnCurve = errors.New("point not on elliptic curve")
   258  
   259  	// errInvalidCurvePoint is returned if a point being unmarshalled as a bn256
   260  	// elliptic curve point is invalid.
   261  	errInvalidCurvePoint = errors.New("invalid elliptic curve point")
   262  
   263  	// invalid ring signed info
   264  	ErrInvalidRingSigned = errors.New("invalid ring signed info")
   265  )
   266  
   267  // newCurvePoint unmarshals a binary blob into a bn256 elliptic curve point,
   268  // returning it, or an error if the point is invalid.
   269  func newCurvePoint(blob []byte) (*bn256.G1, error) {
   270  	p, onCurve := new(bn256.G1).Unmarshal(blob)
   271  	if !onCurve {
   272  		return nil, errNotOnCurve
   273  	}
   274  	gx, gy, _, _ := p.CurvePoints()
   275  	if gx.Cmp(bn256.P) >= 0 || gy.Cmp(bn256.P) >= 0 {
   276  		return nil, errInvalidCurvePoint
   277  	}
   278  	return p, nil
   279  }
   280  
   281  // newTwistPoint unmarshals a binary blob into a bn256 elliptic curve point,
   282  // returning it, or an error if the point is invalid.
   283  func newTwistPoint(blob []byte) (*bn256.G2, error) {
   284  	p, onCurve := new(bn256.G2).Unmarshal(blob)
   285  	if !onCurve {
   286  		return nil, errNotOnCurve
   287  	}
   288  	x2, y2, _, _ := p.CurvePoints()
   289  	if x2.Real().Cmp(bn256.P) >= 0 || x2.Imag().Cmp(bn256.P) >= 0 ||
   290  		y2.Real().Cmp(bn256.P) >= 0 || y2.Imag().Cmp(bn256.P) >= 0 {
   291  		return nil, errInvalidCurvePoint
   292  	}
   293  	return p, nil
   294  }
   295  
   296  // bn256Add implements a native elliptic curve point addition.
   297  type bn256Add struct{}
   298  
   299  // RequiredGas returns the gas required to execute the pre-compiled contract.
   300  func (c *bn256Add) RequiredGas(input []byte) uint64 {
   301  	return params.Bn256AddGas
   302  }
   303  
   304  func (c *bn256Add) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) {
   305  	x, err := newCurvePoint(getData(input, 0, 64))
   306  	if err != nil {
   307  		return nil, err
   308  	}
   309  	y, err := newCurvePoint(getData(input, 64, 64))
   310  	if err != nil {
   311  		return nil, err
   312  	}
   313  	res := new(bn256.G1)
   314  	res.Add(x, y)
   315  	return res.Marshal(), nil
   316  }
   317  
   318  func (c *bn256Add) ValidTx(stateDB StateDB, signer types.Signer, tx *types.Transaction) error {
   319  	return nil
   320  }
   321  
   322  // bn256ScalarMul implements a native elliptic curve scalar multiplication.
   323  type bn256ScalarMul struct{}
   324  
   325  // RequiredGas returns the gas required to execute the pre-compiled contract.
   326  func (c *bn256ScalarMul) RequiredGas(input []byte) uint64 {
   327  	return params.Bn256ScalarMulGas
   328  }
   329  
   330  func (c *bn256ScalarMul) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) {
   331  	p, err := newCurvePoint(getData(input, 0, 64))
   332  	if err != nil {
   333  		return nil, err
   334  	}
   335  	res := new(bn256.G1)
   336  	res.ScalarMult(p, new(big.Int).SetBytes(getData(input, 64, 32)))
   337  	return res.Marshal(), nil
   338  }
   339  
   340  func (c *bn256ScalarMul) ValidTx(stateDB StateDB, signer types.Signer, tx *types.Transaction) error {
   341  	return nil
   342  }
   343  
   344  var (
   345  	// true32Byte is returned if the bn256 pairing check succeeds.
   346  	true32Byte = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
   347  
   348  	// false32Byte is returned if the bn256 pairing check fails.
   349  	false32Byte = make([]byte, 32)
   350  
   351  	// errBadPairingInput is returned if the bn256 pairing input is invalid.
   352  	errBadPairingInput = errors.New("bad elliptic curve pairing size")
   353  )
   354  
   355  // bn256Pairing implements a pairing pre-compile for the bn256 curve
   356  type bn256Pairing struct{}
   357  
   358  // RequiredGas returns the gas required to execute the pre-compiled contract.
   359  func (c *bn256Pairing) RequiredGas(input []byte) uint64 {
   360  	return params.Bn256PairingBaseGas + uint64(len(input)/192)*params.Bn256PairingPerPointGas
   361  }
   362  
   363  func (c *bn256Pairing) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) {
   364  	// Handle some corner cases cheaply
   365  	if len(input)%192 > 0 {
   366  		return nil, errBadPairingInput
   367  	}
   368  	// Convert the input into a set of coordinates
   369  	var (
   370  		cs []*bn256.G1
   371  		ts []*bn256.G2
   372  	)
   373  	for i := 0; i < len(input); i += 192 {
   374  		c, err := newCurvePoint(input[i : i+64])
   375  		if err != nil {
   376  			return nil, err
   377  		}
   378  		t, err := newTwistPoint(input[i+64 : i+192])
   379  		if err != nil {
   380  			return nil, err
   381  		}
   382  		cs = append(cs, c)
   383  		ts = append(ts, t)
   384  	}
   385  	// Execute the pairing checks and return the results
   386  	if bn256.PairingCheck(cs, ts) {
   387  		return true32Byte, nil
   388  	}
   389  	return false32Byte, nil
   390  }
   391  
   392  func (c *bn256Pairing) ValidTx(stateDB StateDB, signer types.Signer, tx *types.Transaction) error {
   393  	return nil
   394  }
   395  
   396  ///////////////////////for wan privacy tx /////////////////////////////////////////////////////////
   397  
   398  var (
   399  	coinSCDefinition = `
   400  	[{"constant": false,"type": "function","stateMutability": "nonpayable","inputs": [{"name": "OtaAddr","type":"string"},{"name": "Value","type": "uint256"}],"name": "buyCoinNote","outputs": [{"name": "OtaAddr","type":"string"},{"name": "Value","type": "uint256"}]},{"constant": false,"type": "function","inputs": [{"name":"RingSignedData","type": "string"},{"name": "Value","type": "uint256"}],"name": "refundCoin","outputs": [{"name": "RingSignedData","type": "string"},{"name": "Value","type": "uint256"}]},{"constant": false,"type": "function","stateMutability": "nonpayable","inputs": [],"name": "getCoins","outputs": [{"name":"Value","type": "uint256"}]}]`
   401  
   402  	stampSCDefinition = `[{"constant": false,"type": "function","stateMutability": "nonpayable","inputs": [{"name":"OtaAddr","type": "string"},{"name": "Value","type": "uint256"}],"name": "buyStamp","outputs": [{"name": "OtaAddr","type": "string"},{"name": "Value","type": "uint256"}]},{"constant": false,"type": "function","inputs": [{"name": "RingSignedData","type": "string"},{"name": "Value","type": "uint256"}],"name": "refundCoin","outputs": [{"name": "RingSignedData","type": "string"},{"name": "Value","type": "uint256"}]},{"constant": false,"type": "function","stateMutability": "nonpayable","inputs": [],"name": "getCoins","outputs": [{"name": "Value","type": "uint256"}]}]`
   403  
   404  	coinAbi, errCoinSCInit               = abi.JSON(strings.NewReader(coinSCDefinition))
   405  	buyIdArr, refundIdArr, getCoinsIdArr [4]byte
   406  
   407  	stampAbi, errStampSCInit = abi.JSON(strings.NewReader(stampSCDefinition))
   408  	stBuyId                  [4]byte
   409  
   410  	errBuyCoin    = errors.New("error in buy coin")
   411  	errRefundCoin = errors.New("error in refund coin")
   412  
   413  	errBuyStamp = errors.New("error in buy stamp")
   414  
   415  	errParameters = errors.New("error parameters")
   416  	errMethodId   = errors.New("error method id")
   417  
   418  	errBalance = errors.New("balance is insufficient")
   419  
   420  	errStampValue = errors.New("stamp value is not support")
   421  
   422  	errCoinValue = errors.New("wancoin value is not support")
   423  
   424  	ErrMismatchedValue = errors.New("mismatched wancoin value")
   425  
   426  	ErrInvalidOTASet = errors.New("invalid OTA mix set")
   427  
   428  	ErrOTAReused = errors.New("OTA is reused")
   429  
   430  	StampValueSet   = make(map[string]string, 5)
   431  	WanCoinValueSet = make(map[string]string, 10)
   432  )
   433  
   434  const (
   435  	Wancoin10  = "10000000000000000000"  //10
   436  	Wancoin20  = "20000000000000000000"  //20
   437  	Wancoin50  = "50000000000000000000"  //50
   438  	Wancoin100 = "100000000000000000000" //100
   439  
   440  	Wancoin200   = "200000000000000000000"   //200
   441  	Wancoin500   = "500000000000000000000"   //500
   442  	Wancoin1000  = "1000000000000000000000"  //1000
   443  	Wancoin5000  = "5000000000000000000000"  //5000
   444  	Wancoin50000 = "50000000000000000000000" //50000
   445  
   446  	WanStampdot001 = "1000000000000000" //0.001
   447  	WanStampdot002 = "2000000000000000" //0.002
   448  	WanStampdot005 = "5000000000000000" //0.005
   449  
   450  	WanStampdot003 = "3000000000000000" //0.003
   451  	WanStampdot006 = "6000000000000000" //0.006
   452  	WanStampdot009 = "9000000000000000" //0.009
   453  
   454  	WanStampdot03 = "30000000000000000"  //0.03
   455  	WanStampdot06 = "60000000000000000"  //0.06
   456  	WanStampdot09 = "90000000000000000"  //0.09
   457  	WanStampdot2  = "200000000000000000" //0.2
   458  	WanStampdot3  = "300000000000000000" //0.3
   459  	WanStampdot5  = "500000000000000000" //0.5
   460  
   461  )
   462  
   463  func init() {
   464  	if errCoinSCInit != nil || errStampSCInit != nil {
   465  		panic("err in coin sc initialize or stamp error initialize ")
   466  	}
   467  
   468  	copy(buyIdArr[:], coinAbi.Methods["buyCoinNote"].Id())
   469  	copy(refundIdArr[:], coinAbi.Methods["refundCoin"].Id())
   470  	copy(getCoinsIdArr[:], coinAbi.Methods["getCoins"].Id())
   471  
   472  	copy(stBuyId[:], stampAbi.Methods["buyStamp"].Id())
   473  
   474  	svaldot001, _ := new(big.Int).SetString(WanStampdot001, 10)
   475  	StampValueSet[svaldot001.Text(16)] = WanStampdot001
   476  
   477  	svaldot002, _ := new(big.Int).SetString(WanStampdot002, 10)
   478  	StampValueSet[svaldot002.Text(16)] = WanStampdot002
   479  
   480  	svaldot005, _ := new(big.Int).SetString(WanStampdot005, 10)
   481  	StampValueSet[svaldot005.Text(16)] = WanStampdot005
   482  
   483  	svaldot003, _ := new(big.Int).SetString(WanStampdot003, 10)
   484  	StampValueSet[svaldot003.Text(16)] = WanStampdot003
   485  
   486  	svaldot006, _ := new(big.Int).SetString(WanStampdot006, 10)
   487  	StampValueSet[svaldot006.Text(16)] = WanStampdot006
   488  
   489  	svaldot009, _ := new(big.Int).SetString(WanStampdot009, 10)
   490  	StampValueSet[svaldot009.Text(16)] = WanStampdot009
   491  
   492  	svaldot03, _ := new(big.Int).SetString(WanStampdot03, 10)
   493  	StampValueSet[svaldot03.Text(16)] = WanStampdot03
   494  
   495  	svaldot06, _ := new(big.Int).SetString(WanStampdot06, 10)
   496  	StampValueSet[svaldot06.Text(16)] = WanStampdot06
   497  
   498  	svaldot09, _ := new(big.Int).SetString(WanStampdot09, 10)
   499  	StampValueSet[svaldot09.Text(16)] = WanStampdot09
   500  
   501  	svaldot2, _ := new(big.Int).SetString(WanStampdot2, 10)
   502  	StampValueSet[svaldot2.Text(16)] = WanStampdot2
   503  
   504  	svaldot3, _ := new(big.Int).SetString(WanStampdot3, 10)
   505  	StampValueSet[svaldot3.Text(16)] = WanStampdot3
   506  
   507  	svaldot5, _ := new(big.Int).SetString(WanStampdot5, 10)
   508  	StampValueSet[svaldot5.Text(16)] = WanStampdot5
   509  
   510  	cval10, _ := new(big.Int).SetString(Wancoin10, 10)
   511  	WanCoinValueSet[cval10.Text(16)] = Wancoin10
   512  
   513  	cval20, _ := new(big.Int).SetString(Wancoin20, 10)
   514  	WanCoinValueSet[cval20.Text(16)] = Wancoin20
   515  
   516  	cval50, _ := new(big.Int).SetString(Wancoin50, 10)
   517  	WanCoinValueSet[cval50.Text(16)] = Wancoin50
   518  
   519  	cval100, _ := new(big.Int).SetString(Wancoin100, 10)
   520  	WanCoinValueSet[cval100.Text(16)] = Wancoin100
   521  
   522  	cval200, _ := new(big.Int).SetString(Wancoin200, 10)
   523  	WanCoinValueSet[cval200.Text(16)] = Wancoin200
   524  
   525  	cval500, _ := new(big.Int).SetString(Wancoin500, 10)
   526  	WanCoinValueSet[cval500.Text(16)] = Wancoin500
   527  
   528  	cval1000, _ := new(big.Int).SetString(Wancoin1000, 10)
   529  	WanCoinValueSet[cval1000.Text(16)] = Wancoin1000
   530  
   531  	cval5000, _ := new(big.Int).SetString(Wancoin5000, 10)
   532  	WanCoinValueSet[cval5000.Text(16)] = Wancoin5000
   533  
   534  	cval50000, _ := new(big.Int).SetString(Wancoin50000, 10)
   535  	WanCoinValueSet[cval50000.Text(16)] = Wancoin50000
   536  
   537  }
   538  
   539  type wanchainStampSC struct{}
   540  
   541  func (c *wanchainStampSC) RequiredGas(input []byte) uint64 {
   542  	// ota balance store gas + ota wanaddr store gas
   543  	return params.SstoreSetGas * 2
   544  }
   545  
   546  func (c *wanchainStampSC) Run(in []byte, contract *Contract, env *EVM) ([]byte, error) {
   547  	if len(in) < 4 {
   548  		return nil, errParameters
   549  	}
   550  
   551  	var methodId [4]byte
   552  	copy(methodId[:], in[:4])
   553  
   554  	if methodId == stBuyId {
   555  		return c.buyStamp(in[4:], contract, env)
   556  	}
   557  
   558  	return nil, errMethodId
   559  }
   560  
   561  func (c *wanchainStampSC) ValidTx(stateDB StateDB, signer types.Signer, tx *types.Transaction) error {
   562  	if stateDB == nil || signer == nil || tx == nil {
   563  		return errParameters
   564  	}
   565  
   566  	payload := tx.Data()
   567  	if len(payload) < 4 {
   568  		return errParameters
   569  	}
   570  
   571  	var methodId [4]byte
   572  	copy(methodId[:], payload[:4])
   573  	if methodId == stBuyId {
   574  		_, err := c.ValidBuyStampReq(stateDB, payload[4:], tx.Value())
   575  		return err
   576  	}
   577  
   578  	return errParameters
   579  }
   580  
   581  func (c *wanchainStampSC) ValidBuyStampReq(stateDB StateDB, payload []byte, value *big.Int) (otaAddr []byte, err error) {
   582  	if stateDB == nil || len(payload) == 0 || value == nil {
   583  		return nil, errors.New("unknown error")
   584  	}
   585  
   586  	var StampInput struct {
   587  		OtaAddr string
   588  		Value   *big.Int
   589  	}
   590  
   591  	err = stampAbi.Unpack(&StampInput, "buyStamp", payload)
   592  	if err != nil || StampInput.Value == nil {
   593  		return nil, errBuyStamp
   594  	}
   595  
   596  	if StampInput.Value.Cmp(value) != 0 {
   597  		return nil, ErrMismatchedValue
   598  	}
   599  
   600  	_, ok := StampValueSet[StampInput.Value.Text(16)]
   601  	if !ok {
   602  		return nil, errStampValue
   603  	}
   604  
   605  	wanAddr, err := hexutil.Decode(StampInput.OtaAddr)
   606  	if err != nil {
   607  		return nil, err
   608  	}
   609  
   610  	ax, err := GetAXFromWanAddr(wanAddr)
   611  	exist, _, err := CheckOTAAXExist(stateDB, ax)
   612  	if err != nil {
   613  		return nil, err
   614  	}
   615  
   616  	if exist {
   617  		return nil, ErrOTAReused
   618  	}
   619  
   620  	return wanAddr, nil
   621  }
   622  
   623  func (c *wanchainStampSC) buyStamp(in []byte, contract *Contract, evm *EVM) ([]byte, error) {
   624  	wanAddr, err := c.ValidBuyStampReq(evm.StateDB, in, contract.value)
   625  	if err != nil {
   626  		return nil, err
   627  	}
   628  
   629  	add, err := AddOTAIfNotExist(evm.StateDB, contract.value, wanAddr)
   630  	if err != nil || !add {
   631  		return nil, errBuyStamp
   632  	}
   633  
   634  	addrSrc := contract.CallerAddress
   635  	balance := evm.StateDB.GetBalance(addrSrc)
   636  
   637  	if balance.Cmp(contract.value) >= 0 {
   638  		// Need check contract value in  build in value sets
   639  		evm.StateDB.SubBalance(addrSrc, contract.value)
   640  		return []byte{1}, nil
   641  	} else {
   642  		return nil, errBalance
   643  	}
   644  }
   645  
   646  type wanCoinSC struct {
   647  }
   648  
   649  func (c *wanCoinSC) RequiredGas(input []byte) uint64 {
   650  	if len(input) < 4 {
   651  		return 0
   652  	}
   653  
   654  	var methodIdArr [4]byte
   655  	copy(methodIdArr[:], input[:4])
   656  
   657  	if methodIdArr == refundIdArr {
   658  
   659  		var RefundStruct struct {
   660  			RingSignedData string
   661  			Value          *big.Int
   662  		}
   663  
   664  		err := coinAbi.Unpack(&RefundStruct, "refundCoin", input[4:])
   665  		if err != nil {
   666  			return params.RequiredGasPerMixPub
   667  		}
   668  
   669  		err, publickeys, _, _, _ := DecodeRingSignOut(RefundStruct.RingSignedData)
   670  		if err != nil {
   671  			return params.RequiredGasPerMixPub
   672  		}
   673  
   674  		mixLen := len(publickeys)
   675  		ringSigDiffRequiredGas := params.RequiredGasPerMixPub * (uint64(mixLen))
   676  
   677  		// ringsign compute gas + ota image key store setting gas
   678  		return ringSigDiffRequiredGas + params.SstoreSetGas
   679  
   680  	} else {
   681  		// ota balance store gas + ota wanaddr store gas
   682  		return params.SstoreSetGas * 2
   683  	}
   684  
   685  }
   686  
   687  func (c *wanCoinSC) Run(in []byte, contract *Contract, evm *EVM) ([]byte, error) {
   688  	if len(in) < 4 {
   689  		return nil, errParameters
   690  	}
   691  
   692  	var methodIdArr [4]byte
   693  	copy(methodIdArr[:], in[:4])
   694  
   695  	if methodIdArr == buyIdArr {
   696  		return c.buyCoin(in[4:], contract, evm)
   697  	} else if methodIdArr == refundIdArr {
   698  		return c.refund(in[4:], contract, evm)
   699  	}
   700  
   701  	return nil, errMethodId
   702  }
   703  
   704  func (c *wanCoinSC) ValidTx(stateDB StateDB, signer types.Signer, tx *types.Transaction) error {
   705  	if stateDB == nil || signer == nil || tx == nil {
   706  		return errParameters
   707  	}
   708  
   709  	payload := tx.Data()
   710  	if len(payload) < 4 {
   711  		return errParameters
   712  	}
   713  
   714  	var methodIdArr [4]byte
   715  	copy(methodIdArr[:], payload[:4])
   716  
   717  	if methodIdArr == buyIdArr {
   718  		_, err := c.ValidBuyCoinReq(stateDB, payload[4:], tx.Value())
   719  		return err
   720  
   721  	} else if methodIdArr == refundIdArr {
   722  		from, err := types.Sender(signer, tx)
   723  		if err != nil {
   724  			return err
   725  		}
   726  
   727  		_, _, err = c.ValidRefundReq(stateDB, payload[4:], from.Bytes())
   728  		return err
   729  	}
   730  
   731  	return errParameters
   732  }
   733  
   734  var (
   735  	ether = new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)
   736  )
   737  
   738  func (c *wanCoinSC) ValidBuyCoinReq(stateDB StateDB, payload []byte, txValue *big.Int) (otaAddr []byte, err error) {
   739  	if stateDB == nil || len(payload) == 0 || txValue == nil {
   740  		return nil, errors.New("unknown error")
   741  	}
   742  
   743  	var outStruct struct {
   744  		OtaAddr string
   745  		Value   *big.Int
   746  	}
   747  
   748  	err = coinAbi.Unpack(&outStruct, "buyCoinNote", payload)
   749  	if err != nil || outStruct.Value == nil {
   750  		return nil, errBuyCoin
   751  	}
   752  
   753  	if outStruct.Value.Cmp(txValue) != 0 {
   754  		return nil, ErrMismatchedValue
   755  	}
   756  
   757  	_, ok := WanCoinValueSet[outStruct.Value.Text(16)]
   758  	if !ok {
   759  		return nil, errCoinValue
   760  	}
   761  
   762  	wanAddr, err := hexutil.Decode(outStruct.OtaAddr)
   763  	if err != nil {
   764  		return nil, err
   765  	}
   766  
   767  	ax, err := GetAXFromWanAddr(wanAddr)
   768  	if err != nil {
   769  		return nil, err
   770  	}
   771  
   772  	exist, _, err := CheckOTAAXExist(stateDB, ax)
   773  	if err != nil {
   774  		return nil, err
   775  	}
   776  
   777  	if exist {
   778  		return nil, ErrOTAReused
   779  	}
   780  
   781  	return wanAddr, nil
   782  }
   783  
   784  func (c *wanCoinSC) buyCoin(in []byte, contract *Contract, evm *EVM) ([]byte, error) {
   785  	otaAddr, err := c.ValidBuyCoinReq(evm.StateDB, in, contract.value)
   786  	if err != nil {
   787  		return nil, err
   788  	}
   789  
   790  	add, err := AddOTAIfNotExist(evm.StateDB, contract.value, otaAddr)
   791  	if err != nil || !add {
   792  		return nil, errBuyCoin
   793  	}
   794  
   795  	addrSrc := contract.CallerAddress
   796  	balance := evm.StateDB.GetBalance(addrSrc)
   797  
   798  	if balance.Cmp(contract.value) >= 0 {
   799  		// Need check contract value in  build in value sets
   800  		evm.StateDB.SubBalance(addrSrc, contract.value)
   801  		return []byte{1}, nil
   802  	} else {
   803  		return nil, errBalance
   804  	}
   805  }
   806  
   807  func (c *wanCoinSC) ValidRefundReq(stateDB StateDB, payload []byte, from []byte) (image []byte, value *big.Int, err error) {
   808  	if stateDB == nil || len(payload) == 0 || len(from) == 0 {
   809  		return nil, nil, errors.New("unknown error")
   810  	}
   811  
   812  	var RefundStruct struct {
   813  		RingSignedData string
   814  		Value          *big.Int
   815  	}
   816  
   817  	err = coinAbi.Unpack(&RefundStruct, "refundCoin", payload)
   818  	if err != nil || RefundStruct.Value == nil {
   819  		return nil, nil, errRefundCoin
   820  	}
   821  
   822  	ringSignInfo, err := FetchRingSignInfo(stateDB, from, RefundStruct.RingSignedData)
   823  	if err != nil {
   824  		return nil, nil, err
   825  	}
   826  
   827  	if ringSignInfo.OTABalance.Cmp(RefundStruct.Value) != 0 {
   828  		return nil, nil, ErrMismatchedValue
   829  	}
   830  
   831  	kix := crypto.FromECDSAPub(ringSignInfo.KeyImage)
   832  	exist, _, err := CheckOTAImageExist(stateDB, kix)
   833  	if err != nil {
   834  		return nil, nil, err
   835  	}
   836  
   837  	if exist {
   838  		return nil, nil, ErrOTAReused
   839  	}
   840  
   841  	return kix, RefundStruct.Value, nil
   842  
   843  }
   844  
   845  func (c *wanCoinSC) refund(all []byte, contract *Contract, evm *EVM) ([]byte, error) {
   846  	kix, value, err := c.ValidRefundReq(evm.StateDB, all, contract.CallerAddress.Bytes())
   847  	if err != nil {
   848  		fmt.Println("failed refund")
   849  		fmt.Println(evm.BlockNumber)
   850  		return nil, err
   851  	}
   852  
   853  	err = AddOTAImage(evm.StateDB, kix, value.Bytes())
   854  	if err != nil {
   855  		return nil, err
   856  	}
   857  
   858  	addrSrc := contract.CallerAddress
   859  	evm.StateDB.AddBalance(addrSrc, value)
   860  	return []byte{1}, nil
   861  
   862  }
   863  
   864  func DecodeRingSignOut(s string) (error, []*ecdsa.PublicKey, *ecdsa.PublicKey, []*big.Int, []*big.Int) {
   865  	ss := strings.Split(s, "+")
   866  	if len(ss) < 4 {
   867  		return ErrInvalidRingSigned, nil, nil, nil, nil
   868  	}
   869  
   870  	ps := ss[0]
   871  	k := ss[1]
   872  	ws := ss[2]
   873  	qs := ss[3]
   874  
   875  	pa := strings.Split(ps, "&")
   876  	publickeys := make([]*ecdsa.PublicKey, 0)
   877  	for _, pi := range pa {
   878  
   879  		publickey := crypto.ToECDSAPub(common.FromHex(pi))
   880  		if publickey == nil || publickey.X == nil || publickey.Y == nil {
   881  			return ErrInvalidRingSigned, nil, nil, nil, nil
   882  		}
   883  
   884  		publickeys = append(publickeys, publickey)
   885  	}
   886  
   887  	keyimgae := crypto.ToECDSAPub(common.FromHex(k))
   888  	if keyimgae == nil || keyimgae.X == nil || keyimgae.Y == nil {
   889  		return ErrInvalidRingSigned, nil, nil, nil, nil
   890  	}
   891  
   892  	wa := strings.Split(ws, "&")
   893  	w := make([]*big.Int, 0)
   894  	for _, wi := range wa {
   895  		bi, err := hexutil.DecodeBig(wi)
   896  		if bi == nil || err != nil {
   897  			return ErrInvalidRingSigned, nil, nil, nil, nil
   898  		}
   899  
   900  		w = append(w, bi)
   901  	}
   902  
   903  	qa := strings.Split(qs, "&")
   904  	q := make([]*big.Int, 0)
   905  	for _, qi := range qa {
   906  		bi, err := hexutil.DecodeBig(qi)
   907  		if bi == nil || err != nil {
   908  			return ErrInvalidRingSigned, nil, nil, nil, nil
   909  		}
   910  
   911  		q = append(q, bi)
   912  	}
   913  
   914  	if len(publickeys) != len(w) || len(publickeys) != len(q) {
   915  		return ErrInvalidRingSigned, nil, nil, nil, nil
   916  	}
   917  
   918  	return nil, publickeys, keyimgae, w, q
   919  }
   920  
   921  type RingSignInfo struct {
   922  	PublicKeys []*ecdsa.PublicKey
   923  	KeyImage   *ecdsa.PublicKey
   924  	W_Random   []*big.Int
   925  	Q_Random   []*big.Int
   926  	OTABalance *big.Int
   927  }
   928  
   929  func FetchRingSignInfo(stateDB StateDB, hashInput []byte, ringSignedStr string) (info *RingSignInfo, err error) {
   930  	if stateDB == nil || hashInput == nil {
   931  		return nil, errParameters
   932  	}
   933  
   934  	infoTmp := new(RingSignInfo)
   935  
   936  	err, infoTmp.PublicKeys, infoTmp.KeyImage, infoTmp.W_Random, infoTmp.Q_Random = DecodeRingSignOut(ringSignedStr)
   937  	if err != nil {
   938  		return nil, err
   939  	}
   940  
   941  	otaLongs := make([][]byte, 0, len(infoTmp.PublicKeys))
   942  	for i := 0; i < len(infoTmp.PublicKeys); i++ {
   943  		otaLongs = append(otaLongs, keystore.ECDSAPKCompression(infoTmp.PublicKeys[i]))
   944  	}
   945  
   946  	exist, balanceGet, _, err := BatCheckOTAExist(stateDB, otaLongs)
   947  	if err != nil {
   948  
   949  		log.Error("verify mix ota fail", "err", err.Error())
   950  		return nil, err
   951  	}
   952  
   953  	if !exist {
   954  		return nil, ErrInvalidOTASet
   955  	}
   956  
   957  	infoTmp.OTABalance = balanceGet
   958  
   959  	valid := crypto.VerifyRingSign(hashInput, infoTmp.PublicKeys, infoTmp.KeyImage, infoTmp.W_Random, infoTmp.Q_Random)
   960  	if !valid {
   961  		return nil, ErrInvalidRingSigned
   962  	}
   963  
   964  	return infoTmp, nil
   965  }
   966  
   967  func GetSupportWanCoinOTABalances() []*big.Int {
   968  	cval10, _ := new(big.Int).SetString(Wancoin10, 10)
   969  	cval20, _ := new(big.Int).SetString(Wancoin20, 10)
   970  	cval50, _ := new(big.Int).SetString(Wancoin50, 10)
   971  	cval100, _ := new(big.Int).SetString(Wancoin100, 10)
   972  
   973  	cval200, _ := new(big.Int).SetString(Wancoin200, 10)
   974  	cval500, _ := new(big.Int).SetString(Wancoin500, 10)
   975  	cval1000, _ := new(big.Int).SetString(Wancoin1000, 10)
   976  	cval5000, _ := new(big.Int).SetString(Wancoin5000, 10)
   977  	cval50000, _ := new(big.Int).SetString(Wancoin50000, 10)
   978  
   979  	wancoinBalances := []*big.Int{
   980  		cval10,
   981  		cval20,
   982  		cval50,
   983  		cval100,
   984  
   985  		cval200,
   986  		cval500,
   987  		cval1000,
   988  		cval5000,
   989  		cval50000,
   990  	}
   991  
   992  	return wancoinBalances
   993  }
   994  
   995  func GetSupportStampOTABalances() []*big.Int {
   996  
   997  	svaldot09, _ := new(big.Int).SetString(WanStampdot09, 10)
   998  	svaldot2, _ := new(big.Int).SetString(WanStampdot2, 10)
   999  	svaldot5, _ := new(big.Int).SetString(WanStampdot5, 10)
  1000  
  1001  	stampBalances := []*big.Int{
  1002  		//svaldot03,
  1003  		//svaldot06,
  1004  		svaldot09,
  1005  		svaldot2,
  1006  		svaldot5,
  1007  	}
  1008  
  1009  	return stampBalances
  1010  }