Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

config: cleanup; params #19

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 67 additions & 55 deletions relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ import (
// PROTOCOL_ID allows data identification by looking at the first few bytes
var PROTOCOL_ID = []byte{0x72, 0x6f, 0x6c, 0x6c}

const (
DEFAULT_SAT_AMOUNT = 1000
DEFAULT_SAT_FEE = 200
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Question]
Shouldn't this be configurable? Because, if I understand right, the whole block data will be posted, not just a commitment to it. Thus, its size can change. Wouldn't it be better to have the fee specified as vBytes so that it changes according to the amount of data being posted?

DEFAULT_PRIVATE_KEY = "5JoQtsKQuH8hC9MyvfJAqo6qmKLm8ePYNucs7tPu2YxG12trzBt"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this. Private keys should be provided and not hardcoded.

)

// Sample data and keys for testing.
// bob key pair is used for signing reveal tx
// internal key pair is used for tweaking
var (
bobPrivateKey = "5JoQtsKQuH8hC9MyvfJAqo6qmKLm8ePYNucs7tPu2YxG12trzBt"
internalPrivateKey = "5JGgKfRy6vEcWBpLJV5FXUfMGNXzvdWzQHUM1rVLEUJfvZUSwvS"
)

// chunkSlice splits input slice into max chunkSize length slices
func chunkSlice(slice []byte, chunkSize int) [][]byte {
var chunks [][]byte
Expand All @@ -46,13 +47,8 @@ func chunkSlice(slice []byte, chunkSize int) [][]byte {
// createTaprootAddress returns an address committing to a Taproot script with
// a single leaf containing the spend path with the script:
// <embedded data> OP_DROP <pubkey> OP_CHECKSIG
func createTaprootAddress(embeddedData []byte) (string, error) {
privKey, err := btcutil.DecodeWIF(bobPrivateKey)
if err != nil {
return "", fmt.Errorf("error decoding bob private key: %v", err)
}

pubKey := privKey.PrivKey.PubKey()
func createTaprootAddress(embeddedData []byte, network *chaincfg.Params, revealPrivateKeyWIF *btcutil.WIF) (string, error) {
pubKey := revealPrivateKeyWIF.PrivKey.PubKey()

// Step 1: Construct the Taproot script with one leaf.
builder := txscript.NewScriptBuilder()
Expand All @@ -73,22 +69,15 @@ func createTaprootAddress(embeddedData []byte) (string, error) {
tapLeaf := txscript.NewBaseTapLeaf(pkScript)
tapScriptTree := txscript.AssembleTaprootScriptTree(tapLeaf)

internalPrivKey, err := btcutil.DecodeWIF(internalPrivateKey)
if err != nil {
return "", fmt.Errorf("error decoding internal private key: %v", err)
}

internalPubKey := internalPrivKey.PrivKey.PubKey()

// Step 2: Generate the Taproot tree.
tapScriptRootHash := tapScriptTree.RootNode.TapHash()
outputKey := txscript.ComputeTaprootOutputKey(
internalPubKey, tapScriptRootHash[:],
pubKey, tapScriptRootHash[:],
)

// Step 3: Generate the Bech32m address.
address, err := btcutil.NewAddressTaproot(
schnorr.SerializePubKey(outputKey), &chaincfg.RegressionNetParams)
schnorr.SerializePubKey(outputKey), network)
if err != nil {
return "", fmt.Errorf("error encoding Taproot address: %v", err)
}
Expand All @@ -107,7 +96,11 @@ func payToTaprootScript(taprootKey *btcec.PublicKey) ([]byte, error) {
// Relayer is a bitcoin client wrapper which provides reader and writer methods
// to write binary blobs to the blockchain.
type Relayer struct {
client *rpcclient.Client
client *rpcclient.Client
network *chaincfg.Params
revealSatAmount btcutil.Amount
revealSatFee btcutil.Amount
Comment on lines +101 to +102
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Proposal]
If these are used also for the commit transaction, proposal to rename to txAmount and txFee as they would be used for the commit and also the reveal

revealPrivateKeyWIF *btcutil.WIF
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Proposal]
Similar, if the same key will be used for the commit tx, proposal to rename to privateKeyWIF

}

// close shuts down the client.
Expand All @@ -120,18 +113,13 @@ func (r Relayer) close() {
// the script satisfying the tapscript spend path that commits to the data. It
// returns the hash of the commit transaction and error, if any.
func (r Relayer) commitTx(addr string) (*chainhash.Hash, error) {
// Create a transaction that sends 0.001 BTC to the given address.
address, err := btcutil.DecodeAddress(addr, &chaincfg.RegressionNetParams)
// Create a transaction that sends revealSatAmount BTC to the given address.
address, err := btcutil.DecodeAddress(addr, r.network)
if err != nil {
return nil, fmt.Errorf("error decoding recipient address: %v", err)
}

amount, err := btcutil.NewAmount(0.001)
if err != nil {
return nil, fmt.Errorf("error creating new amount: %v", err)
}

hash, err := r.client.SendToAddress(address, amount)
hash, err := r.client.SendToAddress(address, btcutil.Amount(r.revealSatAmount))
if err != nil {
return nil, fmt.Errorf("error sending to address: %v", err)
}
Expand All @@ -152,26 +140,14 @@ func (r Relayer) revealTx(embeddedData []byte, commitHash *chainhash.Hash) (*cha
var commitIndex int
var commitOutput *wire.TxOut
for i, out := range rawCommitTx.MsgTx().TxOut {
if out.Value == 100000 {
if out.Value == int64(r.revealSatAmount) {
commitIndex = i
commitOutput = out
break
}
}

privKey, err := btcutil.DecodeWIF(bobPrivateKey)
if err != nil {
return nil, fmt.Errorf("error decoding bob private key: %v", err)
}

pubKey := privKey.PrivKey.PubKey()

internalPrivKey, err := btcutil.DecodeWIF(internalPrivateKey)
if err != nil {
return nil, fmt.Errorf("error decoding internal private key: %v", err)
}

internalPubKey := internalPrivKey.PrivKey.PubKey()
pubKey := r.revealPrivateKeyWIF.PrivKey.PubKey()

// Our script will be a simple <embedded-data> OP_DROP OP_CHECKSIG as the
// sole leaf of a tapscript tree.
Expand All @@ -194,12 +170,12 @@ func (r Relayer) revealTx(embeddedData []byte, commitHash *chainhash.Hash) (*cha
tapScriptTree := txscript.AssembleTaprootScriptTree(tapLeaf)

ctrlBlock := tapScriptTree.LeafMerkleProofs[0].ToControlBlock(
internalPubKey,
pubKey,
)

tapScriptRootHash := tapScriptTree.RootNode.TapHash()
outputKey := txscript.ComputeTaprootOutputKey(
internalPubKey, tapScriptRootHash[:],
pubKey, tapScriptRootHash[:],
)
p2trScript, err := payToTaprootScript(outputKey)
if err != nil {
Expand All @@ -214,7 +190,8 @@ func (r Relayer) revealTx(embeddedData []byte, commitHash *chainhash.Hash) (*cha
},
})
txOut := &wire.TxOut{
Value: 1e3, PkScript: p2trScript,
Value: int64(r.revealSatAmount - r.revealSatFee),
PkScript: p2trScript,
}
tx.AddTxOut(txOut)

Expand All @@ -227,7 +204,7 @@ func (r Relayer) revealTx(embeddedData []byte, commitHash *chainhash.Hash) (*cha
sig, err := txscript.RawTxInTapscriptSignature(
tx, sigHashes, 0, txOut.Value,
txOut.PkScript, tapLeaf, txscript.SigHashDefault,
privKey.PrivKey,
r.revealPrivateKeyWIF.PrivKey,
)

if err != nil {
Expand All @@ -252,11 +229,15 @@ func (r Relayer) revealTx(embeddedData []byte, commitHash *chainhash.Hash) (*cha
}

type Config struct {
Host string
User string
Pass string
HTTPPostMode bool
DisableTLS bool
Host string
User string
Pass string
HTTPPostMode bool
DisableTLS bool
Network string
RevealSatAmount int64
RevealSatFee int64
RevealPrivateKeyWIF string
}

// NewRelayer returns a new relayer. It can error if there's an RPC connection
Expand All @@ -276,8 +257,39 @@ func NewRelayer(config Config) (*Relayer, error) {
if err != nil {
return nil, fmt.Errorf("error creating btcd RPC client: %v", err)
}
var network *chaincfg.Params
switch config.Network {
case "mainnet":
network = &chaincfg.MainNetParams
case "testnet":
network = &chaincfg.TestNet3Params
case "regtest":
network = &chaincfg.RegressionNetParams
default:
network = &chaincfg.RegressionNetParams
}
revealPrivateKeyWIF := config.RevealPrivateKeyWIF
if revealPrivateKeyWIF == "" {
revealPrivateKeyWIF = DEFAULT_PRIVATE_KEY
}
wif, err := btcutil.DecodeWIF(revealPrivateKeyWIF)
if err != nil {
return nil, fmt.Errorf("error decoding reveal private key: %v", err)
}
amount := btcutil.Amount(config.RevealSatAmount)
if amount == 0 {
amount = btcutil.Amount(DEFAULT_SAT_AMOUNT)
}
fee := btcutil.Amount(config.RevealSatFee)
if fee == 0 {
fee = btcutil.Amount(DEFAULT_SAT_FEE)
}
return &Relayer{
client: client,
client: client,
network: network,
revealSatAmount: amount,
revealSatFee: fee,
revealPrivateKeyWIF: wif,
}, nil
}

Expand Down Expand Up @@ -329,7 +341,7 @@ func (r Relayer) Read(height uint64) ([][]byte, error) {

func (r Relayer) Write(data []byte) (*chainhash.Hash, error) {
data = append(PROTOCOL_ID, data...)
address, err := createTaprootAddress(data)
address, err := createTaprootAddress(data, r.network, r.revealPrivateKeyWIF)
if err != nil {
return nil, err
}
Expand Down
10 changes: 5 additions & 5 deletions relayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ func ExampleRelayer_Write() {
func ExampleRelayer_Read() {
// Example usage
relayer, err := bitcoinda.NewRelayer(bitcoinda.Config{
Host: "localhost:18332",
User: "rpcuser",
Pass: "rpcpass",
HTTPPostMode: true,
DisableTLS: true,
Host: "localhost:18332",
User: "rpcuser",
Pass: "rpcpass",
HTTPPostMode: true,
DisableTLS: true,
})
if err != nil {
fmt.Println(err)
Expand Down