btcd

command module
v0.0.0-...-942cd0b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2021 License: MIT Imports: 13 Imported by: 0

README

btcd

A pure Go from-scratch zero-dependecy implementation of Bitcoin for educational purposes. It also includes all of the under the hood crypto primitives such as SHA-256, elliptic curves over finite prime fields math, ECDSA and other.

What can it do?

Right now it can create and validate transactions such as Pay-to-PubKey-Hash and all the operations related to it.

Now you may be asking how can I use btcd to create transactions. Well...

1) You will need to create your own Bitcoin private key, public key and address.
// Generate your own private key, public key, and address.
priv := ecdsa.GenerateKey(elliptic.Secp256k1, "vivelev@icloud.comiamfrombetelgeuse")
// Use some secret of yours for the passphrase above.
pub := priv.PublicKey
address := encoding.Address(&pub, true, true)
// the last two boolean arguments are:
//     1) Should I use compressed format for the address? - YES! Space is valuable!
//     2) Is this address for the testnet or mainnet? - Well, I will use the testnet,
// because I don't have any spare coins. :)

fmt.Printf("My Bitcoin address is: %s. Send me some coins!\n", address)
2) Now go get some testnet coins! Sadly, they aren't worth a dime. :(

I personally use the following faucet: https://coinfaucet.eu/en/btc-testnet/

3) Lets construct the input of our transaction.
3.1) You need to get the ID of the transaction that gave you the coins above.

Navigate to https://mempool.space/testnet and search your address using the search bar. Mine txId was: 68389d05ce8c54041dafcf12820d4246f5ca5128b2d414b5317af58a5274d09e.

3.2) Also, the index of your output (the one with your address).

Since my address showed up second in the column on the right (the outputs), my index is: 1.

3.3) Combining it all: Lets build the transaction input!
// Get the id:
prevTxId := "68389d05ce8c54041dafcf12820d4246f5ca5128b2d414b5317af58a5274d09e"
// Get the index:
prevIndex := 1

// Now construct the input
txIn := tx.TxIn{}
bytes, _ := hex.DecodeString(prevTxId)
copy(txIn.PrevTxId[:], bytes)
txIn.PrevIndex = uint32(prevIndex)
txIn.Testnet = true
4) Decide how much coins you want to send me. ;)

You decide how much. Also, don't forget the fee!!! Here is what I did:

myTotalCoinsInSatoshi, _ := txIn.Value() // 1 satoshi = 1e-8 bitcoin
fmt.Printf("I have %d satoshi.", myTotalCoinsInSatoshi)
// I will send 60% of my satoshi to myself. :)
targetAmount := uint64(0.6 * float64(myTotalCoinsInSatoshi))
// Lets pay the miners!
fee := uint64(1500)
// Calculate the change amount, I will send this back to `address`.
changeAmount := myTotalCoinsInSatoshi - targetAmount - fee
5) Lets build the transaction output.

I want you to send me the coins to: mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv. Here is how:

// Create the target transaction output
targetAddress := "mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv"
targetH160, _ := encoding.AddressToPubKeyHash(targetAddress)
targetScript := script.NewP2PKHScript(targetH160)
targetTxOut := tx.TxOut{
    Amount:       targetAmount,
    ScriptPubKey: targetScript,
}
6) Lets not forget amount the change, that's money!
// Create the change transaction output
changeH160, _ := encoding.AddressToPubKeyHash(address)
changeScript := script.NewP2PKHScript(changeH160)
changeTxOut := tx.TxOut{
    Amount:       changeAmount,
    ScriptPubKey: changeScript,
}
7) We are almost done! Now we need to combine the inputs & outputs into a single transaction.
// Combine the inputs & outputs in a transaction
transaction := tx.Tx{
    Version:  1,
    TxIns:    []txscript.TxIn{txIn},
    TxOuts:   []txscript.TxOut{targetTxOut, changeTxOut},
    Locktime: 0,
    Testnet:  true,
}
// And sign the inputs please. In this way you verify that the money
// you are about to spend are, indeed, yours.
transaction.SignInput(0, priv)
8) Print the hex of the transaction, so we can broadcast it to the network!
bytes, _ = transaction.Marshal()
fmt.Printf("Tx's Hex: %s\n", hex.EncodeToString(bytes))

Now you can navigate to a service like https://live.blockcypher.com/btc-testnet/pushtx/ and broadcast your transaction to the world! Soon, you will be able to do so directly from btcd.

The full source of making a transaction is in makeTransaction.go

Unit tests

$ go test ./...

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
crypto
ecdsa
Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as defined in https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm
Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as defined in https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm
elliptic
Package elliptic implements several standard elliptic curves over prime finite fields of the form: y^2 = x^3 + a*x + b (mod p)
Package elliptic implements several standard elliptic curves over prime finite fields of the form: y^2 = x^3 + a*x + b (mod p)
hash
package hash implements various hashing algorithms used in bitcoin
package hash implements various hashing algorithms used in bitcoin
Package encoding provides different encodings used in bitcoin and also utility functions that use this encodings.
Package encoding provides different encodings used in bitcoin and also utility functions that use this encodings.
package network implements the Bitcoin peer-to-peer network protocol.
package network implements the Bitcoin peer-to-peer network protocol.
Implementation of Bitcoin's Script language.
Implementation of Bitcoin's Script language.
Implementation of Bitcoin transaction.
Implementation of Bitcoin transaction.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL