plugeth/transaction.go

207 lines
4.7 KiB
Go
Raw Normal View History

2013-12-26 11:45:52 +00:00
package main
import (
"math/big"
2014-01-08 22:42:11 +00:00
"fmt"
2014-01-05 00:55:03 +00:00
"github.com/obscuren/secp256k1-go"
2014-01-02 23:43:49 +00:00
_"encoding/hex"
_"crypto/sha256"
2013-12-26 11:45:52 +00:00
_ "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
*/
2013-12-27 11:07:37 +00:00
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)
2013-12-26 11:45:52 +00:00
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 {
2014-01-03 23:33:41 +00:00
nonce string
2013-12-26 11:45:52 +00:00
sender string
2013-12-28 01:22:42 +00:00
recipient string
2014-01-03 23:33:41 +00:00
value uint64
2013-12-26 11:45:52 +00:00
fee uint32
data []string
memory []int
2013-12-28 01:22:42 +00:00
lastTx string
v uint32
r, s []byte
2013-12-26 11:45:52 +00:00
}
2014-01-03 23:33:41 +00:00
func NewTransaction(to string, value uint64, data []string) *Transaction {
2013-12-26 11:45:52 +00:00
tx := Transaction{sender: "1234567890", recipient: to, value: value}
2014-01-03 23:33:41 +00:00
tx.nonce = "0"
2013-12-26 11:45:52 +00:00
tx.fee = 0//uint32((ContractFee + MemoryFee * float32(len(tx.data))) * 1e8)
2013-12-28 01:22:42 +00:00
tx.lastTx = "0"
2013-12-26 11:45:52 +00:00
// 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)
2013-12-26 11:45:52 +00:00
}
tx.data[i] = instr
}
2014-01-08 22:42:11 +00:00
tx.Sign([]byte("privkey"))
tx.Sender()
2013-12-26 11:45:52 +00:00
return &tx
}
2014-01-02 23:43:49 +00:00
func (tx *Transaction) Hash() []byte {
preEnc := []interface{}{
tx.nonce,
tx.recipient,
tx.value,
tx.fee,
tx.data,
}
return Sha256Bin(Encode(preEnc))
2014-01-02 23:43:49 +00:00
}
2014-01-05 00:55:03 +00:00
func (tx *Transaction) IsContract() bool {
return tx.recipient == ""
}
2014-01-08 22:42:11 +00:00
func (tx *Transaction) Signature(key []byte) []byte {
hash := tx.Hash()
2014-01-08 22:42:11 +00:00
sec := Sha256Bin(key)
2014-01-05 00:55:03 +00:00
sig, _ := secp256k1.Sign(hash, sec)
return sig
}
func (tx *Transaction) PublicKey() []byte {
2014-01-08 22:42:11 +00:00
hash := Sha256Bin(tx.Hash())
sig := append(tx.r, tx.s...)
2014-01-05 00:55:03 +00:00
pubkey, _ := secp256k1.RecoverPubkey(hash, sig)
return pubkey
}
2014-01-08 22:42:11 +00:00
func (tx *Transaction) Sender() []byte {
pubkey := tx.PublicKey()
2014-01-08 22:42:11 +00:00
// 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:]
}
2014-01-08 22:42:11 +00:00
func (tx *Transaction) Sign(privk []byte) {
sig := tx.Signature(privk)
2014-01-08 22:42:11 +00:00
// 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 {
2013-12-26 11:45:52 +00:00
// Prepare the transaction for serialization
preEnc := []interface{}{
tx.nonce,
2013-12-28 01:22:42 +00:00
tx.recipient,
tx.value,
tx.fee,
2013-12-26 11:45:52 +00:00
tx.data,
tx.v,
tx.r,
tx.s,
2013-12-26 11:45:52 +00:00
}
2013-12-28 14:18:08 +00:00
return Encode(preEnc)
2013-12-28 01:22:42 +00:00
}
func (tx *Transaction) UnmarshalRlp(data []byte) {
2014-01-08 22:42:11 +00:00
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()
2013-12-28 01:22:42 +00:00
}
2014-01-08 22:42:11 +00:00
tx.v = uint32(decoder.Get(5).AsUint())
tx.r = decoder.Get(6).AsBytes()
tx.s = decoder.Get(7).AsBytes()
2013-12-26 11:45:52 +00:00
}
func InitFees() {
// Base for 2**60
b60 := new(big.Int)
2013-12-27 11:07:37 +00:00
b60.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0))
2013-12-26 11:45:52 +00:00
// Base for 2**80
b80 := new(big.Int)
b80.Exp(big.NewInt(2), big.NewInt(80), big.NewInt(0))
2014-01-03 23:33:41 +00:00
StepFee.Exp(big.NewInt(10), big.NewInt(16), big.NewInt(0))
//StepFee.Div(b60, big.NewInt(64))
2013-12-26 11:45:52 +00:00
//fmt.Println("StepFee:", StepFee)
2013-12-27 11:07:37 +00:00
TxFee.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0))
2013-12-26 11:45:52 +00:00
//fmt.Println("TxFee:", TxFee)
2013-12-27 11:07:37 +00:00
ContractFee.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0))
//fmt.Println("ContractFee:", ContractFee)
MemFee.Div(b60, big.NewInt(4))
2013-12-26 11:45:52 +00:00
//fmt.Println("MemFee:", MemFee)
2013-12-27 11:07:37 +00:00
DataFee.Div(b60, big.NewInt(16))
2013-12-26 11:45:52 +00:00
//fmt.Println("DataFee:", DataFee)
2013-12-27 11:07:37 +00:00
CryptoFee.Div(b60, big.NewInt(16))
2013-12-26 11:45:52 +00:00
//fmt.Println("CrytoFee:", CryptoFee)
2013-12-27 11:07:37 +00:00
ExtroFee.Div(b60, big.NewInt(16))
2013-12-26 11:45:52 +00:00
//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)
}