Ejemplo n.º 1
0
func makeTransactionForChainWithHoursFee(t *testing.T, bc *Blockchain,
	ux coin.UxOut, sec cipher.SecKey, hours, fee uint64) (coin.Transaction, cipher.SecKey) {
	chrs := ux.CoinHours(bc.Time())
	if chrs < hours+fee {
		log.Panicf("CoinHours underflow. Have %d, need at least %d", chrs,
			hours+fee)
	}
	assert.Equal(t, cipher.AddressFromPubKey(cipher.PubKeyFromSecKey(sec)), ux.Body.Address)
	knownUx, exists := bc.GetUnspent().Get(ux.Hash())
	assert.True(t, exists)
	assert.Equal(t, knownUx, ux)
	tx := coin.Transaction{}
	tx.PushInput(ux.Hash())
	p, newSec := cipher.GenerateKeyPair()
	addr := cipher.AddressFromPubKey(p)
	tx.PushOutput(addr, 1e6, hours)
	coinsOut := ux.Body.Coins - 1e6
	if coinsOut > 0 {
		tx.PushOutput(genAddress, coinsOut, chrs-hours-fee)
	}
	tx.SignInputs([]cipher.SecKey{sec})
	assert.Equal(t, len(tx.Sigs), 1)
	assert.Nil(t, cipher.ChkSig(ux.Body.Address, cipher.AddSHA256(tx.HashInner(), tx.In[0]), tx.Sigs[0]))
	tx.UpdateHeader()
	assert.Nil(t, tx.Verify())
	err := bc.VerifyTransaction(tx)
	assert.Nil(t, err)
	return tx, newSec
}
Ejemplo n.º 2
0
func TestTransactionSignInputs(t *testing.T) {
	tx := &Transaction{}
	// Panics if txns already signed
	tx.Sigs = append(tx.Sigs, cipher.Sig{})
	assert.Panics(t, func() { tx.SignInputs([]cipher.SecKey{}) })
	// Panics if not enough keys
	tx = &Transaction{}
	ux, s := makeUxOutWithSecret(t)
	tx.PushInput(ux.Hash())
	ux2, s2 := makeUxOutWithSecret(t)
	tx.PushInput(ux2.Hash())
	tx.PushOutput(makeAddress(), 40, 80)
	assert.Equal(t, len(tx.Sigs), 0)
	assert.Panics(t, func() { tx.SignInputs([]cipher.SecKey{s}) })
	assert.Equal(t, len(tx.Sigs), 0)
	// Valid signing
	h := tx.HashInner()
	assert.NotPanics(t, func() { tx.SignInputs([]cipher.SecKey{s, s2}) })
	assert.Equal(t, len(tx.Sigs), 2)
	assert.Equal(t, tx.HashInner(), h)
	p := cipher.PubKeyFromSecKey(s)
	a := cipher.AddressFromPubKey(p)
	p = cipher.PubKeyFromSecKey(s2)
	a2 := cipher.AddressFromPubKey(p)
	assert.Nil(t, cipher.ChkSig(a, cipher.AddSHA256(h, tx.In[0]), tx.Sigs[0]))
	assert.Nil(t, cipher.ChkSig(a2, cipher.AddSHA256(h, tx.In[1]), tx.Sigs[1]))
	assert.NotNil(t, cipher.ChkSig(a, h, tx.Sigs[1]))
	assert.NotNil(t, cipher.ChkSig(a2, h, tx.Sigs[0]))
}
Ejemplo n.º 3
0
// addBlockToBlockchain test helper function
// Adds 2 blocks to the blockchain and return an unspent that has >0 coin hours
func addBlockToBlockchain(t *testing.T, bc *Blockchain) (coin.Block, coin.UxOut) {
	// Split the genesis block into two transactions
	assert.Equal(t, len(bc.GetUnspent().Array()), 1)
	ux := bc.GetUnspent().Array()[0]
	assert.Equal(t, ux.Body.Address, genAddress)
	pub := cipher.PubKeyFromSecKey(genSecret)
	assert.Equal(t, genAddress, cipher.AddressFromPubKey(pub))
	sig := cipher.SignHash(ux.Hash(), genSecret)
	assert.Nil(t, cipher.ChkSig(ux.Body.Address, ux.Hash(), sig))

	tx, sec := makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 0, 0)
	b, err := bc.NewBlockFromTransactions(coin.Transactions{tx}, _incTime)
	assert.Nil(t, err)
	assertExecuteBlock(t, bc, b, tx)
	assert.Equal(t, len(bc.GetUnspent().Array()), 2)

	// Spend one of them
	// The other will have hours now
	ux = coin.UxOut{}
	for _, u := range bc.GetUnspent().Pool {
		if u.Body.Address != genAddress {
			ux = u
			break
		}
	}
	assert.NotEqual(t, ux.Body.Address, cipher.Address{})
	assert.NotEqual(t, ux.Body.Address, genAddress)
	pub = cipher.PubKeyFromSecKey(sec)
	addr := cipher.AddressFromPubKey(pub)
	assert.Equal(t, ux.Body.Address, addr)
	tx, _ = makeTransactionForChainWithHoursFee(t, bc, ux, sec, 0, 0)
	b, err = bc.NewBlockFromTransactions(coin.Transactions{tx},
		bc.Time()+_incTime)
	assert.Nil(t, err)
	assertExecuteBlock(t, bc, b, tx)
	assert.Equal(t, len(bc.GetUnspent().Array()), 2)

	// Check that the output in the 2nd block is owned by genesis,
	// and has coin hours
	for _, u := range bc.GetUnspent().Pool {
		if u.Body.Address == genAddress {
			ux = u
			break
		}
	}
	assert.Equal(t, ux.Body.Address, genAddress)
	assert.Equal(t, ux.Head.BkSeq, uint64(1))
	assert.True(t, ux.CoinHours(bc.Time()) > 0)

	return b, ux
}
Ejemplo n.º 4
0
//test signatures
func TestCrypto2(t *testing.T) {
	a := "5a42c0643bdb465d90bf673b99c14f5fa02db71513249d904573d2b8b63d353d"
	b, err := hex.DecodeString(a)
	if err != nil {
		t.Fatal(err)
	}

	if len(b) != 32 {
		t.Fatal()
	}

	seckey := cipher.NewSecKey(b)
	pubkey := cipher.PubKeyFromSecKey(seckey)

	addr := cipher.AddressFromPubKey(pubkey)
	_ = addr

	test := []byte("test message")
	hash := cipher.SumSHA256(test)
	err = cipher.TestSecKeyHash(seckey, hash)
	if err != nil {
		t.Fatal()
	}

}
Ejemplo n.º 5
0
func (wlt *Wallet) GenerateAddresses(num int) []cipher.Address {
	var seckeys []cipher.SecKey
	var sd []byte
	var err error
	if len(wlt.Entries) == 0 {
		sd, seckeys = cipher.GenerateDeterministicKeyPairsSeed([]byte(wlt.getLastSeed()), num)
	} else {
		sd, err = hex.DecodeString(wlt.getLastSeed())
		if err != nil {
			log.Panicf("decode hex seed failed,%v", err)
		}
		sd, seckeys = cipher.GenerateDeterministicKeyPairsSeed(sd, num)
	}
	wlt.setLastSeed(hex.EncodeToString(sd))
	addrs := make([]cipher.Address, len(seckeys))
	for i, s := range seckeys {
		p := cipher.PubKeyFromSecKey(s)
		a := cipher.AddressFromPubKey(p)
		addrs[i] = a
		wlt.Entries = append(wlt.Entries, WalletEntry{
			Address: a,
			Secret:  s,
			Public:  p,
		})
	}
	return addrs
}
Ejemplo n.º 6
0
func getKeyEntry(pub cipher.PubKey, sec cipher.SecKey) KeyEntry {

	var e KeyEntry

	//skycoin address
	if BitcoinAddress == false {
		e = KeyEntry{
			Address: cipher.AddressFromPubKey(pub).String(),
			Public:  pub.Hex(),
			Secret:  sec.Hex(),
		}
	}

	//bitcoin address
	if BitcoinAddress == true {
		e = KeyEntry{
			Address: cipher.BitcoinAddressFromPubkey(pub),
			Public:  pub.Hex(),
			Secret:  cipher.BitcoinWalletImportFormatFromSeckey(sec),
		}
	}

	//hide the secret key
	if HideSeckey == true {
		e.Secret = ""
	}

	return e
}
Ejemplo n.º 7
0
func NewWalletEntryFromKeypair(pub cipher.PubKey, sec cipher.SecKey) WalletEntry {
	return WalletEntry{
		Address: cipher.AddressFromPubKey(pub),
		Public:  pub,
		Secret:  sec,
	}
}
Ejemplo n.º 8
0
func TestFullTransaction(t *testing.T) {
	p1, s1 := cipher.GenerateKeyPair()
	a1 := cipher.AddressFromPubKey(p1)
	bc := NewBlockchain()
	bc.CreateGenesisBlock(a1, _genTime, _genCoins)
	tx := Transaction{}
	ux := bc.Unspent.Array()[0]
	tx.PushInput(ux.Hash())
	p2, s2 := cipher.GenerateKeyPair()
	a2 := cipher.AddressFromPubKey(p2)
	tx.PushOutput(a1, ux.Body.Coins-6e6, 100)
	tx.PushOutput(a2, 1e6, 100)
	tx.PushOutput(a2, 5e6, 100)
	tx.SignInputs([]cipher.SecKey{s1})
	tx.UpdateHeader()
	assert.Nil(t, tx.Verify())
	assert.Nil(t, bc.VerifyTransaction(tx))
	b, err := bc.NewBlockFromTransactions(Transactions{tx}, bc.Time()+_incTime)
	assert.Nil(t, err)
	_, err = bc.ExecuteBlock(b)
	assert.Nil(t, err)

	txo := CreateUnspents(bc.Head().Head, tx)
	tx = Transaction{}
	assert.Equal(t, txo[0].Body.Address, a1)
	assert.Equal(t, txo[1].Body.Address, a2)
	assert.Equal(t, txo[2].Body.Address, a2)
	ux0, ok := bc.Unspent.Get(txo[0].Hash())
	assert.True(t, ok)
	ux1, ok := bc.Unspent.Get(txo[1].Hash())
	assert.True(t, ok)
	ux2, ok := bc.Unspent.Get(txo[2].Hash())
	assert.True(t, ok)
	tx.PushInput(ux0.Hash())
	tx.PushInput(ux1.Hash())
	tx.PushInput(ux2.Hash())
	tx.PushOutput(a2, 10e6, 200)
	tx.PushOutput(a1, ux.Body.Coins-10e6, 100)
	tx.SignInputs([]cipher.SecKey{s1, s2, s2})
	tx.UpdateHeader()
	assert.Nil(t, tx.Verify())
	assert.Nil(t, bc.VerifyTransaction(tx))
	b, err = bc.NewBlockFromTransactions(Transactions{tx}, bc.Time()+_incTime)
	assert.Nil(t, err)
	_, err = bc.ExecuteBlock(b)
	assert.Nil(t, err)
}
Ejemplo n.º 9
0
// Creates a ReadableWalletEntry given a pubkey hex string.  The Secret field
// is left empty.
func ReadableWalletEntryFromPubkey(pub string) ReadableWalletEntry {
	pubkey := cipher.MustPubKeyFromHex(pub)
	addr := cipher.AddressFromPubKey(pubkey)
	return ReadableWalletEntry{
		Address: addr.String(),
		Public:  pub,
	}
}
Ejemplo n.º 10
0
func makeUxBodyWithSecret(t *testing.T) (coin.UxBody, cipher.SecKey) {
	p, s := cipher.GenerateKeyPair()
	return coin.UxBody{
		SrcTransaction: cipher.SumSHA256(randBytes(t, 128)),
		Address:        cipher.AddressFromPubKey(p),
		Coins:          10e6,
		Hours:          100,
	}, s
}
Ejemplo n.º 11
0
//Generate Blockchain configuration for client only Blockchain, not intended to be synced to network
func NewLocalBlockchain() Blockchain {
	pubkey, seckey := cipher.GenerateKeyPair() //generate new/random pubkey/private key

	fmt.Printf("NewLocalBlockchain: genesis address seckey= %v \n", seckey.Hex())
	VC := NewBlockchain()
	VC.SecKey = seckey
	VC.Genesis.GenesisAddress = cipher.AddressFromPubKey(pubkey)
	VC.Genesis.GenesisTime = uint64(time.Now().Unix())
	VC.InjectGenesisBlock()
	return VC
}
Ejemplo n.º 12
0
func TestAddress1(t *testing.T) {
	a := "02fa939957e9fc52140e180264e621c2576a1bfe781f88792fb315ca3d1786afb8"
	b, err := hex.DecodeString(a)
	if err != nil {
		t.Fatal(err)
	}
	addr := cipher.AddressFromPubKey(cipher.NewPubKey(b))
	_ = addr

	///func SignHash(hash cipher.SHA256, sec SecKey) (Sig, error) {

}
Ejemplo n.º 13
0
func TestAddress2(t *testing.T) {
	a := "5a42c0643bdb465d90bf673b99c14f5fa02db71513249d904573d2b8b63d353d"
	b, err := hex.DecodeString(a)
	if err != nil {
		t.Fail()
	}

	if len(b) != 32 {
		t.Fail()
	}

	seckey := cipher.NewSecKey(b)
	pubkey := cipher.PubKeyFromSecKey(seckey)
	addr := cipher.AddressFromPubKey(pubkey)
	_ = addr

	///func SignHash(hash cipher.SHA256, sec SecKey) (Sig, error) {

}
Ejemplo n.º 14
0
func makeAddress() cipher.Address {
	p, _ := cipher.GenerateKeyPair()
	return cipher.AddressFromPubKey(p)
}
Ejemplo n.º 15
0
func addPrivateKeyCMD() gcli.Command {
	name := "addPrivateKey"
	return gcli.Command{
		Name:      name,
		Usage:     "Add a private key to specific wallet",
		ArgsUsage: "[private key]",
		Description: fmt.Sprintf(`Add a private key to specific wallet, the default
		wallet(%s/%s) will be 
		used if the wallet file or path is not specified`,
			cfg.WalletDir, cfg.DefaultWalletName),
		Flags: []gcli.Flag{
			gcli.StringFlag{
				Name:  "f",
				Usage: "[wallet file or path] private key will be added to this wallet",
			},
		},
		OnUsageError: onCommandUsageError(name),
		Action: func(c *gcli.Context) error {
			// get private key
			skStr := c.Args().First()
			if skStr == "" {
				gcli.ShowSubcommandHelp(c)
				return nil
			}

			// get wallet file path
			w := c.String("f")
			if w == "" {
				w = filepath.Join(cfg.WalletDir, cfg.DefaultWalletName)
			}

			if !strings.HasSuffix(w, walletExt) {
				return errWalletName
			}

			// only wallet file name, no path.
			if filepath.Base(w) == w {
				w = filepath.Join(cfg.WalletDir, w)
			}

			wlt, err := wallet.Load(w)
			if err != nil {
				errorWithHelp(c, err)
				return nil
			}

			sk, err := cipher.SecKeyFromHex(skStr)
			if err != nil {
				return fmt.Errorf("invalid private key: %s, must be an hex string of length 64", skStr)
			}

			pk := cipher.PubKeyFromSecKey(sk)
			addr := cipher.AddressFromPubKey(pk)

			entry := wallet.WalletEntry{
				Address: addr,
				Public:  pk,
				Secret:  sk,
			}

			if err := wlt.AddEntry(entry); err != nil {
				return err
			}

			dir, err := filepath.Abs(filepath.Dir(w))
			if err != nil {
				return err
			}

			if err := wlt.Save(dir); err != nil {
				return errors.New("save wallet failed")
			}

			fmt.Println("success")

			return nil
		},
	}
	// Commands = append(Commands, cmd)
}
Ejemplo n.º 16
0
func TestVerifyTransactionSpending(t *testing.T) {
	ft := FakeTree{}
	bc := NewBlockchain(&ft, nil)
	bc.CreateGenesisBlock(genAddress, _genCoins, _genTime)

	// Overspending hours

	tx := coin.Transaction{}
	uxs := bc.GetUnspent().Array()
	tx.PushInput(uxs[0].Hash())
	tx.PushOutput(genAddress, 1e6, uxs[0].Body.Hours)
	tx.PushOutput(genAddress, uxs[0].Body.Coins-1e6, 1)
	uxIn, err := bc.GetUnspent().GetMultiple(tx.In)
	assert.Nil(t, err)
	uxOut := coin.CreateUnspents(bc.Head().Head, tx)
	assertError(t, coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut),
		"Insufficient coin hours")

	// add block to blockchain.
	_, ux := addBlockToBlockchain(t, bc)
	// addBlockToBlockchain(t, bc)

	// Valid
	tx, _ = makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100, 50)
	uxIn, err = bc.GetUnspent().GetMultiple(tx.In)
	assert.Nil(t, err)
	uxOut = coin.CreateUnspents(bc.Head().Head, tx)
	assert.Nil(t, coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut))

	// Destroying coins
	tx = coin.Transaction{}
	tx.PushInput(ux.Hash())
	tx.PushOutput(genAddress, 1e6, 100)
	tx.PushOutput(genAddress, 10e6, 100)
	uxIn, err = bc.GetUnspent().GetMultiple(tx.In)
	assert.Nil(t, err)
	uxOut = coin.CreateUnspents(bc.Head().Head, tx)
	err = coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut)
	assert.NotNil(t, err)
	assert.Equal(t, err.Error(),
		"Transactions may not create or destroy coins")
	assertError(t, coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut),
		"Transactions may not create or destroy coins")

	// Insufficient coins
	tx = coin.Transaction{}
	tx.PushInput(ux.Hash())
	p, s := cipher.GenerateKeyPair()
	a := cipher.AddressFromPubKey(p)
	coins := ux.Body.Coins
	assert.True(t, coins > 1e6)
	tx.PushOutput(a, 1e6, 100)
	tx.PushOutput(genAddress, coins-1e6, 100)
	tx.SignInputs([]cipher.SecKey{genSecret})
	tx.UpdateHeader()
	b, err := bc.NewBlockFromTransactions(coin.Transactions{tx}, bc.Time()+_incTime)
	assert.Nil(t, err)
	uxs, err = bc.ExecuteBlock(&b)
	assert.Nil(t, err)
	tx = coin.Transaction{}
	tx.PushInput(uxs[0].Hash())
	tx.PushOutput(a, 10e6, 1)
	tx.SignInputs([]cipher.SecKey{s})
	tx.UpdateHeader()
	uxIn, err = bc.GetUnspent().GetMultiple(tx.In)
	assert.Nil(t, err)
	uxOut = coin.CreateUnspents(bc.Head().Head, tx)
	assertError(t, coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut),
		"Insufficient coins")
}
Ejemplo n.º 17
0
package coin

import (
	"encoding/hex"
	"math/rand"
	"testing"
	"time"

	"github.com/skycoin/skycoin/src/cipher"
	"github.com/stretchr/testify/assert"
)

var (
	genPublic, genSecret        = cipher.GenerateKeyPair()
	genAddress                  = cipher.AddressFromPubKey(genPublic)
	testMaxSize                 = 1024 * 1024
	_genTime             uint64 = 1000
	_incTime             uint64 = 3600 * 1000
	_genCoins            uint64 = 1000e6
	_genCoinHours        uint64 = 1000 * 1000
)

func assertError(t *testing.T, err error, msg string) {
	assert.NotNil(t, err)
	assert.Equal(t, err.Error(), msg)
}

func tNow() uint64 {
	return uint64(time.Now().UTC().Unix())
}