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 }