From 0769e79d9b370b1b5106d21c57aeed4065914428 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sat, 4 Mar 2023 12:12:29 -0800 Subject: [PATCH 1/3] config: cleanup; params --- relayer.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/relayer.go b/relayer.go index 4566b11..28eb4e6 100644 --- a/relayer.go +++ b/relayer.go @@ -46,7 +46,7 @@ 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: // OP_DROP OP_CHECKSIG -func createTaprootAddress(embeddedData []byte) (string, error) { +func createTaprootAddress(embeddedData []byte, network *chaincfg.Params) (string, error) { privKey, err := btcutil.DecodeWIF(bobPrivateKey) if err != nil { return "", fmt.Errorf("error decoding bob private key: %v", err) @@ -88,7 +88,7 @@ func createTaprootAddress(embeddedData []byte) (string, error) { // 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) } @@ -108,6 +108,7 @@ func payToTaprootScript(taprootKey *btcec.PublicKey) ([]byte, error) { // to write binary blobs to the blockchain. type Relayer struct { client *rpcclient.Client + network *chaincfg.Params } // close shuts down the client. @@ -121,7 +122,7 @@ func (r Relayer) close() { // 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) + address, err := btcutil.DecodeAddress(addr, r.network) if err != nil { return nil, fmt.Errorf("error decoding recipient address: %v", err) } @@ -257,6 +258,7 @@ type Config struct { Pass string HTTPPostMode bool DisableTLS bool + Network *chaincfg.Params } // NewRelayer returns a new relayer. It can error if there's an RPC connection @@ -278,6 +280,7 @@ func NewRelayer(config Config) (*Relayer, error) { } return &Relayer{ client: client, + network: config.Network, }, nil } @@ -329,7 +332,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) if err != nil { return nil, err } From aca0f034c9929dff6ce2cbe0da0c6d45bdc0668b Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sat, 4 Mar 2023 12:22:09 -0800 Subject: [PATCH 2/3] cfg: sat amount, sat fee, priv key --- relayer.go | 120 ++++++++++++++++++++++++++---------------------- relayer_test.go | 10 ++-- 2 files changed, 69 insertions(+), 61 deletions(-) diff --git a/relayer.go b/relayer.go index 28eb4e6..97433d7 100644 --- a/relayer.go +++ b/relayer.go @@ -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 + DEFAULT_PRIVATE_KEY = "5JoQtsKQuH8hC9MyvfJAqo6qmKLm8ePYNucs7tPu2YxG12trzBt" +) + // 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 @@ -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: // OP_DROP OP_CHECKSIG -func createTaprootAddress(embeddedData []byte, network *chaincfg.Params) (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() @@ -73,17 +69,10 @@ func createTaprootAddress(embeddedData []byte, network *chaincfg.Params) (string 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. @@ -107,8 +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 - network *chaincfg.Params + client *rpcclient.Client + network *chaincfg.Params + revealSatAmount btcutil.Amount + revealSatFee btcutil.Amount + revealPrivateKeyWIF *btcutil.WIF } // close shuts down the client. @@ -121,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. + // 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) } @@ -153,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 OP_DROP OP_CHECKSIG as the // sole leaf of a tapscript tree. @@ -195,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 { @@ -215,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) @@ -228,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 { @@ -253,12 +229,14 @@ func (r Relayer) revealTx(embeddedData []byte, commitHash *chainhash.Hash) (*cha } type Config struct { - Host string - User string - Pass string - HTTPPostMode bool - DisableTLS bool - Network *chaincfg.Params + Host string + User string + Pass string + HTTPPostMode bool + DisableTLS bool + Network string + RevealSatAmount int64 + RevealPrivateKeyWIF string } // NewRelayer returns a new relayer. It can error if there's an RPC connection @@ -278,9 +256,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.RevealSatAmount) + if fee == 0 { + fee = btcutil.Amount(DEFAULT_SAT_FEE) + } return &Relayer{ - client: client, - network: config.Network, + client: client, + network: network, + revealSatAmount: amount, + revealSatFee: fee, + revealPrivateKeyWIF: wif, }, nil } @@ -332,7 +340,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, r.network) + address, err := createTaprootAddress(data, r.network, r.revealPrivateKeyWIF) if err != nil { return nil, err } diff --git a/relayer_test.go b/relayer_test.go index 4c4d543..4b0a524 100644 --- a/relayer_test.go +++ b/relayer_test.go @@ -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) From efd5ce9dfcfa73efd70add15a3cd9846a30badaa Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Sat, 4 Mar 2023 14:09:48 -0800 Subject: [PATCH 3/3] cfg: sat fee --- relayer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/relayer.go b/relayer.go index 97433d7..0c385da 100644 --- a/relayer.go +++ b/relayer.go @@ -236,6 +236,7 @@ type Config struct { DisableTLS bool Network string RevealSatAmount int64 + RevealSatFee int64 RevealPrivateKeyWIF string } @@ -279,7 +280,7 @@ func NewRelayer(config Config) (*Relayer, error) { if amount == 0 { amount = btcutil.Amount(DEFAULT_SAT_AMOUNT) } - fee := btcutil.Amount(config.RevealSatAmount) + fee := btcutil.Amount(config.RevealSatFee) if fee == 0 { fee = btcutil.Amount(DEFAULT_SAT_FEE) }