package main import ( "math/big" "fmt" "github.com/obscuren/secp256k1-go" _"encoding/hex" _"crypto/sha256" _ "bytes" ) /* Transaction Contract Size ------------------------------------------- sender sender 20 bytes recipient 0x0 20 bytes value endowment 4 bytes (uint32) fee fee 4 bytes (uint32) d_size o_size 4 bytes (uint32) data ops * signature signature 64 bytes */ var StepFee *big.Int = new(big.Int) var TxFee *big.Int = new(big.Int) var ContractFee *big.Int = new(big.Int) var MemFee *big.Int = new(big.Int) var DataFee *big.Int = new(big.Int) var CryptoFee *big.Int = new(big.Int) var ExtroFee *big.Int = new(big.Int) var Period1Reward *big.Int = new(big.Int) var Period2Reward *big.Int = new(big.Int) var Period3Reward *big.Int = new(big.Int) var Period4Reward *big.Int = new(big.Int) type Transaction struct { nonce string sender string recipient string value uint64 fee uint32 data []string memory []int lastTx string v uint32 r, s []byte } func NewTransaction(to string, value uint64, data []string) *Transaction { tx := Transaction{sender: "1234567890", recipient: to, value: value} tx.nonce = "0" tx.fee = 0//uint32((ContractFee + MemoryFee * float32(len(tx.data))) * 1e8) tx.lastTx = "0" // Serialize the data tx.data = make([]string, len(data)) for i, val := range data { instr, err := CompileInstr(val) if err != nil { //fmt.Printf("compile error:%d %v\n", i+1, err) } tx.data[i] = instr } tx.Sign([]byte("privkey")) tx.Sender() return &tx } func (tx *Transaction) Hash() []byte { preEnc := []interface{}{ tx.nonce, tx.recipient, tx.value, tx.fee, tx.data, } return Sha256Bin(Encode(preEnc)) } func (tx *Transaction) IsContract() bool { return tx.recipient == "" } func (tx *Transaction) Signature(key []byte) []byte { hash := tx.Hash() sec := Sha256Bin(key) sig, _ := secp256k1.Sign(hash, sec) return sig } func (tx *Transaction) PublicKey() []byte { hash := Sha256Bin(tx.Hash()) sig := append(tx.r, tx.s...) pubkey, _ := secp256k1.RecoverPubkey(hash, sig) return pubkey } func (tx *Transaction) Sender() []byte { pubkey := tx.PublicKey() // Validate the returned key. // Return nil if public key isn't in full format (04 = full, 03 = compact) if pubkey[0] != 4 { return nil } return Sha256Bin(pubkey[1:65])[12:] } func (tx *Transaction) Sign(privk []byte) { sig := tx.Signature(privk) // Add 27 so we get either 27 or 28 (for positive and negative) tx.v = uint32(sig[64]) + 27 tx.r = sig[:32] tx.s = sig[32:65] } func (tx *Transaction) MarshalRlp() []byte { // Prepare the transaction for serialization preEnc := []interface{}{ tx.nonce, tx.recipient, tx.value, tx.fee, tx.data, tx.v, tx.r, tx.s, } return Encode(preEnc) } func (tx *Transaction) UnmarshalRlp(data []byte) { decoder := NewRlpDecoder(data) tx.nonce = decoder.Get(0).AsString() tx.recipient = decoder.Get(0).AsString() tx.value = decoder.Get(2).AsUint() tx.fee = uint32(decoder.Get(3).AsUint()) d := decoder.Get(4) tx.data = make([]string, d.Length()) fmt.Println(d.Get(0)) for i := 0; i < d.Length(); i++ { tx.data[i] = d.Get(i).AsString() } tx.v = uint32(decoder.Get(5).AsUint()) tx.r = decoder.Get(6).AsBytes() tx.s = decoder.Get(7).AsBytes() } func InitFees() { // Base for 2**60 b60 := new(big.Int) b60.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0)) // Base for 2**80 b80 := new(big.Int) b80.Exp(big.NewInt(2), big.NewInt(80), big.NewInt(0)) StepFee.Exp(big.NewInt(10), big.NewInt(16), big.NewInt(0)) //StepFee.Div(b60, big.NewInt(64)) //fmt.Println("StepFee:", StepFee) TxFee.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0)) //fmt.Println("TxFee:", TxFee) ContractFee.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0)) //fmt.Println("ContractFee:", ContractFee) MemFee.Div(b60, big.NewInt(4)) //fmt.Println("MemFee:", MemFee) DataFee.Div(b60, big.NewInt(16)) //fmt.Println("DataFee:", DataFee) CryptoFee.Div(b60, big.NewInt(16)) //fmt.Println("CrytoFee:", CryptoFee) ExtroFee.Div(b60, big.NewInt(16)) //fmt.Println("ExtroFee:", ExtroFee) Period1Reward.Mul(b80, big.NewInt(1024)) //fmt.Println("Period1Reward:", Period1Reward) Period2Reward.Mul(b80, big.NewInt(512)) //fmt.Println("Period2Reward:", Period2Reward) Period3Reward.Mul(b80, big.NewInt(256)) //fmt.Println("Period3Reward:", Period3Reward) Period4Reward.Mul(b80, big.NewInt(128)) //fmt.Println("Period4Reward:", Period4Reward) }