mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
Replace p2pkh with p2pk (#1650)
* Replace p2pkh with p2pk * Fix tests * Fix comments and variable names * Add README.md for genkeypair * Rename pubkey->publicKey * Rename p2pkh to p2pk * Use util.PublicKeySize where needed * Remove redundant pointer * Fix comment * Rename pubKey->publicKey
This commit is contained in:
parent
d01a213f3d
commit
6afc06ce58
9
cmd/genkeypair/README.md
Normal file
9
cmd/genkeypair/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
genkeypair
|
||||
========
|
||||
|
||||
A tool for generating private-key-address pairs.
|
||||
|
||||
Note: This tool prints unencrypted private keys and is not recommended for day
|
||||
to day use, and is intended mainly for tests.
|
||||
|
||||
In order to manage your funds it's recommended to use [kaspawallet](../kaspawallet)
|
26
cmd/genkeypair/config.go
Normal file
26
cmd/genkeypair/config.go
Normal file
@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/jessevdk/go-flags"
|
||||
"github.com/kaspanet/kaspad/infrastructure/config"
|
||||
)
|
||||
|
||||
type configFlags struct {
|
||||
config.NetworkFlags
|
||||
}
|
||||
|
||||
func parseConfig() (*configFlags, error) {
|
||||
cfg := &configFlags{}
|
||||
parser := flags.NewParser(cfg, flags.PrintErrors|flags.HelpFlag)
|
||||
_, err := parser.Parse()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = cfg.ResolveNetwork(parser)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
27
cmd/genkeypair/main.go
Normal file
27
cmd/genkeypair/main.go
Normal file
@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg, err := parseConfig()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
privateKey, publicKey, err := libkaspawallet.CreateKeyPair()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
addr, err := util.NewAddressPublicKey(publicKey, cfg.NetParams().Prefix)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Private key: %x\n", privateKey)
|
||||
fmt.Printf("Address: %s\n", addr)
|
||||
}
|
@ -26,9 +26,9 @@ func CreateKeyPair() ([]byte, []byte, error) {
|
||||
}
|
||||
|
||||
func addressFromPublicKey(params *dagconfig.Params, publicKeySerialized []byte) (util.Address, error) {
|
||||
addr, err := util.NewAddressPubKeyHashFromPublicKey(publicKeySerialized[:], params.Prefix)
|
||||
addr, err := util.NewAddressPublicKey(publicKeySerialized[:], params.Prefix)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to generate p2pkh address")
|
||||
return nil, errors.Wrap(err, "Failed to generate p2pk address")
|
||||
}
|
||||
|
||||
return addr, nil
|
||||
|
@ -254,7 +254,7 @@ func extractTransaction(psTx *serialization.PartiallySignedTransaction) (*extern
|
||||
psTx.Tx.Inputs[i].SignatureScript = sigScript
|
||||
} else {
|
||||
if len(input.PubKeySignaturePairs) > 1 {
|
||||
return nil, errors.Errorf("Cannot sign on P2PKH when len(input.PubKeySignaturePairs) > 1")
|
||||
return nil, errors.Errorf("Cannot sign on P2PK when len(input.PubKeySignaturePairs) > 1")
|
||||
}
|
||||
|
||||
if input.PubKeySignaturePairs[0].Signature == nil {
|
||||
@ -263,7 +263,6 @@ func extractTransaction(psTx *serialization.PartiallySignedTransaction) (*extern
|
||||
|
||||
sigScript, err := txscript.NewScriptBuilder().
|
||||
AddData(input.PubKeySignaturePairs[0].Signature).
|
||||
AddData(input.PubKeySignaturePairs[0].PubKey).
|
||||
Script()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -156,7 +156,7 @@ func TestMultisig(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestP2PKH(t *testing.T) {
|
||||
func TestP2PK(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||
params.BlockCoinbaseMaturity = 0
|
||||
tc, teardown, err := consensus.NewFactory().NewTestConsensus(params, false, "TestMultisig")
|
||||
@ -181,7 +181,7 @@ func TestP2PKH(t *testing.T) {
|
||||
t.Fatalf("Address: %+v", err)
|
||||
}
|
||||
|
||||
if _, ok := address.(*util.AddressPubKeyHash); !ok {
|
||||
if _, ok := address.(*util.AddressPublicKey); !ok {
|
||||
t.Fatalf("The address is of unexpected type")
|
||||
}
|
||||
|
||||
|
@ -58,9 +58,9 @@ func TestValidateTransactionInContextAndPopulateMassAndFee(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to serialize public key: %v", err)
|
||||
}
|
||||
addr, err := util.NewAddressPubKeyHashFromPublicKey(publicKeySerialized[:], params.Prefix)
|
||||
addr, err := util.NewAddressPublicKey(publicKeySerialized[:], params.Prefix)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate p2pkh address: %v", err)
|
||||
t.Fatalf("Failed to generate p2pk address: %v", err)
|
||||
}
|
||||
scriptPublicKey, err := txscript.PayToAddrScript(addr)
|
||||
if err != nil {
|
||||
@ -261,9 +261,9 @@ func TestSigningTwoInputs(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to serialize public key: %v", err)
|
||||
}
|
||||
addr, err := util.NewAddressPubKeyHashFromPublicKey(publicKeySerialized[:], params.Prefix)
|
||||
addr, err := util.NewAddressPublicKey(publicKeySerialized[:], params.Prefix)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate p2pkh address: %v", err)
|
||||
t.Fatalf("Failed to generate p2pk address: %v", err)
|
||||
}
|
||||
|
||||
scriptPublicKey, err := txscript.PayToAddrScript(addr)
|
||||
|
@ -108,86 +108,86 @@ func TestCalculateSignatureHash(t *testing.T) {
|
||||
|
||||
// sigHashAll
|
||||
{name: "native-all-0", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
expectedSignatureHash: "c899a5ea7414f0bbfd77e50674f46da34ce8722b928d4362a4b4b727c69c6499"},
|
||||
expectedSignatureHash: "3e4a8effa6903dea5f762754ec410d732114ec2907e5bcbae7b6dd8d3f309a10"},
|
||||
{name: "native-all-0-modify-input-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyInput(1), // should change the hash
|
||||
expectedSignatureHash: "faf3b9db2e07b1c14b2df02002d3e40f1e430f177ac5cd3354c84dad8fbe72ce"},
|
||||
expectedSignatureHash: "0bd2947383101f9708d94d5799626c69c1b8472d2de66523c90c4a674e99cc51"},
|
||||
{name: "native-all-0-modify-output-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // should change the hash
|
||||
expectedSignatureHash: "3a557c5b873aab72dcb81649642e1d7a63b75dcdcc74e19d340964a9e0eac76c"},
|
||||
expectedSignatureHash: "ae69aa1372e958f069bf52d2628ead7ee789f195340b615ff0bcb6f01a995810"},
|
||||
{name: "native-all-0-modify-sequence-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // should change the hash
|
||||
expectedSignatureHash: "2dd5fe8f9fa4bf551ea2f080a26e07b2462083e12d3b2ed01cb9369a61920665"},
|
||||
expectedSignatureHash: "51295575e7efc1fe1c2e741ade49089e3d780d15d26e9a0b18b3d90e35caf795"},
|
||||
{name: "native-all-anyonecanpay-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "19fe2e0db681017f318fda705a39bbbad9c1085514cfbcff6fac01e1725f758b"},
|
||||
expectedSignatureHash: "0a13d3cab42a6cf3a7ef96f7b28c9bb0d98c209a3032ff85a6bfa7dac520f2c2"},
|
||||
{name: "native-all-anyonecanpay-0-modify-input-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyInput(0), // should change the hash
|
||||
expectedSignatureHash: "5b21d492560a1c794595f769b3ae3c151775b9cfc4029d17c53f1856e1005da4"},
|
||||
expectedSignatureHash: "aeaa56f5bc99daea0be5ed4b047808ce0123a81ac89c6089b72fa7199f5cd1c6"},
|
||||
{name: "native-all-anyonecanpay-0-modify-input-1", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyInput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "19fe2e0db681017f318fda705a39bbbad9c1085514cfbcff6fac01e1725f758b"},
|
||||
expectedSignatureHash: "0a13d3cab42a6cf3a7ef96f7b28c9bb0d98c209a3032ff85a6bfa7dac520f2c2"},
|
||||
{name: "native-all-anyonecanpay-0-modify-sequence", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "19fe2e0db681017f318fda705a39bbbad9c1085514cfbcff6fac01e1725f758b"},
|
||||
expectedSignatureHash: "0a13d3cab42a6cf3a7ef96f7b28c9bb0d98c209a3032ff85a6bfa7dac520f2c2"},
|
||||
|
||||
// sigHashNone
|
||||
{name: "native-none-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
expectedSignatureHash: "fafabaabf6349fee4e18626b4eff015472f2317576a8f4bf7b0eea1df6f3e32b"},
|
||||
expectedSignatureHash: "da53f7c726b55357adb1b644265fe7b9b7897cadde91a942d6127195c2ce99dc"},
|
||||
{name: "native-none-0-modify-output-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "fafabaabf6349fee4e18626b4eff015472f2317576a8f4bf7b0eea1df6f3e32b"},
|
||||
expectedSignatureHash: "da53f7c726b55357adb1b644265fe7b9b7897cadde91a942d6127195c2ce99dc"},
|
||||
{name: "native-none-0-modify-sequence-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifySequence(0), // should change the hash
|
||||
expectedSignatureHash: "daee0700e0ed4ab9f50de24d83e0bfce62999474ec8ceeb537ea35980662b601"},
|
||||
expectedSignatureHash: "72c07c152a3792fb863d2de219ab4e863fe6779dc970a5c3958e26b3a3b9f139"},
|
||||
{name: "native-none-0-modify-sequence-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "fafabaabf6349fee4e18626b4eff015472f2317576a8f4bf7b0eea1df6f3e32b"},
|
||||
expectedSignatureHash: "da53f7c726b55357adb1b644265fe7b9b7897cadde91a942d6127195c2ce99dc"},
|
||||
{name: "native-none-anyonecanpay-0", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "4e5c2d895f9711dc89c19d49ba478e9c8f4be0d82c9bd6b60d0361eb9b5296bc"},
|
||||
expectedSignatureHash: "18eb79df328a516708f792cadfc4bf2be21b6add35fb6637a20347d532b1dce1"},
|
||||
{name: "native-none-anyonecanpay-0-modify-amount-spent", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyAmountSpent(0), // should change the hash
|
||||
expectedSignatureHash: "9ce2f75eafc85b8e19133942c3143d14b61f2e7cc479fbc6d2fca026e50897f1"},
|
||||
expectedSignatureHash: "674a8e6effa0bbfdb3df3ca45a7b17ab695cc0f9b3e0519e5bff165de13604e2"},
|
||||
{name: "native-none-anyonecanpay-0-modify-script-public-key", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||
modificationFunction: modifyScriptPublicKey(0), // should change the hash
|
||||
expectedSignatureHash: "c6c364190520fe6c0419c2f45e25bf084356333b03ac7aaec28251126398bda3"},
|
||||
expectedSignatureHash: "7a879d339c9b948c5264f1c0b8463f551221b2dcd575623f178cbbfcf7e01987"},
|
||||
|
||||
// sigHashSingle
|
||||
{name: "native-single-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
expectedSignatureHash: "6ff01d5d7cd82e24bc9ca0edec8bd6931ffb5aa1d303f07ca05dc89757343a92"},
|
||||
expectedSignatureHash: "99c0a4a381fed9dbd651450d6ca969a6e8cdd941e9d73be086a1ba6c90fb630f"},
|
||||
{name: "native-single-0-modify-output-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(0), // should change the hash
|
||||
expectedSignatureHash: "d62af956aea369365bacc7e7f1aac106836994f1648311e82dd38da822c8771e"},
|
||||
expectedSignatureHash: "92189a32391ca50a454d1853efed55acb1c49993911a1201df9891c866c483ee"},
|
||||
{name: "native-single-0-modify-output-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "6ff01d5d7cd82e24bc9ca0edec8bd6931ffb5aa1d303f07ca05dc89757343a92"},
|
||||
expectedSignatureHash: "99c0a4a381fed9dbd651450d6ca969a6e8cdd941e9d73be086a1ba6c90fb630f"},
|
||||
{name: "native-single-0-modify-sequence-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifySequence(0), // should change the hash
|
||||
expectedSignatureHash: "46692229d45bf2ceacb18960faba29753e325c0ade26ecf94495b91daacb828d"},
|
||||
expectedSignatureHash: "765e2289df98b3a5269f112d4b36d57fe32c74d42e04a3046c6a3c8dd78a4121"},
|
||||
{name: "native-single-0-modify-sequence-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "6ff01d5d7cd82e24bc9ca0edec8bd6931ffb5aa1d303f07ca05dc89757343a92"},
|
||||
expectedSignatureHash: "99c0a4a381fed9dbd651450d6ca969a6e8cdd941e9d73be086a1ba6c90fb630f"},
|
||||
{name: "native-single-2-no-corresponding-output", tx: nativeTx, hashType: single, inputIndex: 2,
|
||||
expectedSignatureHash: "d3cc385082a7f272ec2c8aae7f3a96ab2f49a4a4e1ed44d61af34058a7721281"},
|
||||
expectedSignatureHash: "43de18c04d7fde81f49a40228d8730b4ceb0c66c77841c22622f59554769dd13"},
|
||||
{name: "native-single-2-no-corresponding-output-modify-output-1", tx: nativeTx, hashType: single, inputIndex: 2,
|
||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||
expectedSignatureHash: "d3cc385082a7f272ec2c8aae7f3a96ab2f49a4a4e1ed44d61af34058a7721281"},
|
||||
expectedSignatureHash: "43de18c04d7fde81f49a40228d8730b4ceb0c66c77841c22622f59554769dd13"},
|
||||
{name: "native-single-anyonecanpay-0", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 0,
|
||||
expectedSignatureHash: "408fcfd8ceca135c0f54569ccf8ac727e1aa6b5a15f87ccca765f1d5808aa4ea"},
|
||||
expectedSignatureHash: "2e270f86fd68f780a5aa8d250364ab6786d990040268e5d561d09dde365dfab7"},
|
||||
{name: "native-single-anyonecanpay-2-no-corresponding-output", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 2,
|
||||
expectedSignatureHash: "685fac0d0b9dd3c5556f266714c4f7f93475d49fa12befb18e8297bc062aeaba"},
|
||||
expectedSignatureHash: "afc05dd6b4a530cc3a4d7d23126548bd1f31c793e9282cbbfa27ff5566219501"},
|
||||
|
||||
// subnetwork transaction
|
||||
{name: "subnetwork-all-0", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
expectedSignatureHash: "0e8b1433b761a220a61c0dc1f0fda909d49cef120d98d9f87344fef52dac0d8b"},
|
||||
expectedSignatureHash: "5a67423ee048e067b94e2d4fc2960f62eceff6aa8b6c5ad71e3b7b7e5ff6bad7"},
|
||||
{name: "subnetwork-all-modify-payload", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyPayload, // should change the hash
|
||||
expectedSignatureHash: "087315acb9193eaa14929dbe3d0ace80238aebe13eab3bf8db6c0a0d7ddb782e"},
|
||||
expectedSignatureHash: "0d3bc5914da8dc8df081945fea1255359f380ca9baa8b31dfb3657c1e3c6038a"},
|
||||
{name: "subnetwork-all-modify-gas", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifyGas, // should change the hash
|
||||
expectedSignatureHash: "07a90408ef45864ae8354b07a74cf826a4621391425ba417470a6e680af4ce70"},
|
||||
expectedSignatureHash: "70abe9f947d0a0f5d735f9a063db8af41fe5902940f2693a1782119063097094"},
|
||||
{name: "subnetwork-all-subnetwork-id", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||
modificationFunction: modifySubnetworkID, // should change the hash
|
||||
expectedSignatureHash: "4ca44c2e35729ae5efe831a77027f1a58a41dbdd853459c26cbfe7d6c88783fb"},
|
||||
expectedSignatureHash: "571a0b7ea905b7a6ff7ab825b72d23f911bac0bfaa7c4c97a4887a3d090925d4"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
@ -1,10 +1,9 @@
|
||||
package hashes
|
||||
|
||||
import (
|
||||
"hash"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/pkg/errors"
|
||||
"hash"
|
||||
)
|
||||
|
||||
// HashWriter is used to incrementally hash data without concatenating all of the data to a single buffer
|
||||
|
@ -15,7 +15,7 @@ although it is still fairly powerful.
|
||||
|
||||
## Examples
|
||||
|
||||
* [Standard Pay-to-pubkey-hash Script](http://godoc.org/github.com/kaspanet/kaspad/txscript#example-PayToAddrScript)
|
||||
* [Standard Pay-to-pubkey Script](http://godoc.org/github.com/kaspanet/kaspad/txscript#example-PayToAddrScript)
|
||||
Demonstrates creating a script which pays to a kaspa address. It also
|
||||
prints the created script hex and uses the DisasmString function to display
|
||||
the disassembled script.
|
||||
|
@ -22,7 +22,7 @@ func ExamplePayToAddrScript() {
|
||||
// which is useful to ensure the accuracy of the address and determine
|
||||
// the address type. It is also required for the upcoming call to
|
||||
// PayToAddrScript.
|
||||
addressStr := "kaspa:qqfgqp8l9l90zwetj84k2jcac2m8falvvyy8xjtnhdac2m8falvvyvc9fuvqt"
|
||||
addressStr := "kaspa:qqj9fg59mptxkr9j0y53j5mwurcmda5mtza9n6v9pm9uj8h0wgk6uma5pvumr"
|
||||
address, err := util.DecodeAddress(addressStr, util.Bech32PrefixKaspa)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
@ -45,15 +45,15 @@ func ExamplePayToAddrScript() {
|
||||
fmt.Println("Script Disassembly:", disasm)
|
||||
|
||||
// Output:
|
||||
// Script Hex: 76aa20128004ff2fcaf13b2b91eb654b1dc2b674f7ec6108734973bb7b856ce9efd8c288ac
|
||||
// Script Disassembly: OP_DUP OP_BLAKE2B 128004ff2fcaf13b2b91eb654b1dc2b674f7ec6108734973bb7b856ce9efd8c2 OP_EQUALVERIFY OP_CHECKSIG
|
||||
// Script Hex: 202454a285d8566b0cb2792919536ee0f1b6f69b58ba59e9850ecbc91eef722daeac
|
||||
// Script Disassembly: 2454a285d8566b0cb2792919536ee0f1b6f69b58ba59e9850ecbc91eef722dae OP_CHECKSIG
|
||||
}
|
||||
|
||||
// This example demonstrates extracting information from a standard public key
|
||||
// script.
|
||||
func ExampleExtractScriptPubKeyAddress() {
|
||||
// Start with a standard pay-to-pubkey-hash script.
|
||||
scriptHex := "76aa20128004ff2fcaf13b2b91eb65128004ff2fcaf13b2b91eb654b1dc2b674f7ec6188ac"
|
||||
// Start with a standard pay-to-pubkey script.
|
||||
scriptHex := "2089ac24ea10bb751af4939623ccc5e550d96842b64e8fca0f63e94b4373fd555eac"
|
||||
script, err := hex.DecodeString(scriptHex)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
@ -74,6 +74,6 @@ func ExampleExtractScriptPubKeyAddress() {
|
||||
fmt.Println("Address:", address)
|
||||
|
||||
// Output:
|
||||
// Script Class: pubkeyhash
|
||||
// Address: kaspa:qqfgqp8l9l90zwetj84k2y5qqnljljh38v4er6m9fvwu9dn57lkxztu8quj75
|
||||
// Script Class: pubkey
|
||||
// Address: kaspa:qzy6cf82zzah2xh5jwtz8nx9u4gdj6zzke8gljs0v055ksmnl424u6fv7ajrs
|
||||
}
|
||||
|
@ -48,16 +48,7 @@ func SignatureScript(tx *externalapi.DomainTransaction, idx int, hashType consen
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pk, err := privKey.SchnorrPublicKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pkData, err := pk.Serialize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewScriptBuilder().AddData(sig).AddData(pkData[:]).Script()
|
||||
return NewScriptBuilder().AddData(sig).Script()
|
||||
}
|
||||
|
||||
func sign(dagParams *dagconfig.Params, tx *externalapi.DomainTransaction, idx int,
|
||||
@ -71,7 +62,7 @@ func sign(dagParams *dagconfig.Params, tx *externalapi.DomainTransaction, idx in
|
||||
}
|
||||
|
||||
switch class {
|
||||
case PubKeyHashTy:
|
||||
case PubKeyTy:
|
||||
// look up key for address
|
||||
key, err := kdb.GetKey(address)
|
||||
if err != nil {
|
||||
|
@ -143,7 +143,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Pay to Pubkey Hash (merging with correct)
|
||||
// Pay to Pubkey (merging with correct)
|
||||
for _, hashType := range hashTypes {
|
||||
for _, input := range tx.Inputs {
|
||||
input.UTXOEntry = utxo.NewUTXOEntry(500, scriptPubKey, false, 100)
|
||||
@ -180,14 +180,14 @@ func TestSignTxOutput(t *testing.T) {
|
||||
|
||||
err = checkScripts(msg, tx, i, sigScript, scriptPubKey)
|
||||
if err != nil {
|
||||
t.Errorf("twice signed script invalid for "+
|
||||
t.Fatalf("twice signed script invalid for "+
|
||||
"%s: %v", msg, err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pay to Pubkey Hash (compressed)
|
||||
// Pay to Pubkey
|
||||
for _, hashType := range hashTypes {
|
||||
for i := range tx.Inputs {
|
||||
msg := fmt.Sprintf("%d:%d", hashType, i)
|
||||
@ -213,8 +213,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
address, err := util.NewAddressPubKeyHash(
|
||||
util.HashBlake2b(serializedPubKey[:]), util.Bech32PrefixKaspaTest)
|
||||
address, err := util.NewAddressPublicKey(serializedPubKey[:], util.Bech32PrefixKaspaTest)
|
||||
if err != nil {
|
||||
t.Errorf("failed to make address for %s: %v",
|
||||
msg, err)
|
||||
@ -238,7 +237,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Pay to Pubkey Hash with duplicate merge
|
||||
// Pay to Pubkey with duplicate merge
|
||||
for _, hashType := range hashTypes {
|
||||
for i := range tx.Inputs {
|
||||
msg := fmt.Sprintf("%d:%d", hashType, i)
|
||||
@ -264,8 +263,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
address, err := util.NewAddressPubKeyHash(
|
||||
util.HashBlake2b(serializedPubKey[:]), util.Bech32PrefixKaspaTest)
|
||||
address, err := util.NewAddressPublicKey(serializedPubKey[:], util.Bech32PrefixKaspaTest)
|
||||
if err != nil {
|
||||
t.Errorf("failed to make address for %s: %v",
|
||||
msg, err)
|
||||
@ -316,7 +314,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
|
||||
// As before, but with p2sh now.
|
||||
|
||||
// Pay to Pubkey Hash
|
||||
// Pay to Pubkey
|
||||
for _, hashType := range hashTypes {
|
||||
for i := range tx.Inputs {
|
||||
msg := fmt.Sprintf("%d:%d", hashType, i)
|
||||
@ -342,8 +340,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
address, err := util.NewAddressPubKeyHash(
|
||||
util.HashBlake2b(serializedPubKey[:]), util.Bech32PrefixKaspaTest)
|
||||
address, err := util.NewAddressPublicKey(serializedPubKey[:], util.Bech32PrefixKaspaTest)
|
||||
if err != nil {
|
||||
t.Errorf("failed to make address for %s: %v",
|
||||
msg, err)
|
||||
@ -381,7 +378,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Pay to Pubkey Hash (compressed) with duplicate merge
|
||||
// Pay to Pubkey with duplicate merge
|
||||
for _, hashType := range hashTypes {
|
||||
for i := range tx.Inputs {
|
||||
msg := fmt.Sprintf("%d:%d", hashType, i)
|
||||
@ -407,8 +404,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
break
|
||||
}
|
||||
|
||||
address, err := util.NewAddressPubKeyHash(
|
||||
util.HashBlake2b(serializedPubKey[:]), util.Bech32PrefixKaspaTest)
|
||||
address, err := util.NewAddressPublicKey(serializedPubKey[:], util.Bech32PrefixKaspaTest)
|
||||
if err != nil {
|
||||
t.Errorf("failed to make address for %s: %v",
|
||||
msg, err)
|
||||
@ -474,7 +470,7 @@ func TestSignTxOutput(t *testing.T) {
|
||||
}
|
||||
|
||||
func generateKeys() (keyPair *secp256k1.SchnorrKeyPair, scriptPublicKey *externalapi.ScriptPublicKey,
|
||||
addressPubKeyHash *util.AddressPubKeyHash, err error) {
|
||||
addressPubKeyHash *util.AddressPublicKey, err error) {
|
||||
|
||||
key, err := secp256k1.GenerateSchnorrKeyPair()
|
||||
if err != nil {
|
||||
@ -490,8 +486,7 @@ func generateKeys() (keyPair *secp256k1.SchnorrKeyPair, scriptPublicKey *externa
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Errorf("failed to serialize a pubkey for %s: %s", pubKey, err)
|
||||
}
|
||||
address, err := util.NewAddressPubKeyHash(
|
||||
util.HashBlake2b(serializedPubKey[:]), util.Bech32PrefixKaspaTest)
|
||||
address, err := util.NewAddressPublicKey(serializedPubKey[:], util.Bech32PrefixKaspaTest)
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Errorf("failed to make address for %s: %s", serializedPubKey, err)
|
||||
}
|
||||
@ -534,12 +529,10 @@ var (
|
||||
oldCompressedScriptPubKey = &externalapi.ScriptPublicKey{[]byte{0x76, 0xa9, 0x14, 0x27, 0x4d, 0x9f, 0x7f,
|
||||
0x61, 0x7e, 0x7c, 0x7a, 0x1c, 0x1f, 0xb2, 0x75, 0x79, 0x10,
|
||||
0x43, 0x65, 0x68, 0x27, 0x9d, 0x86, 0x88, 0xac}, 0}
|
||||
p2pkhScriptPubKey = &externalapi.ScriptPublicKey{[]byte{0x76, 0xaa, 0x20,
|
||||
0x51, 0x9c, 0x25, 0xca, 0x95, 0xa0, 0xd8, 0xcd,
|
||||
0xf5, 0xb8, 0x3f, 0x96, 0xa1, 0x5e, 0x8c, 0x1a,
|
||||
0xae, 0x33, 0xeb, 0x50, 0xc8, 0x66, 0xc9, 0xd0,
|
||||
0xa5, 0xce, 0x3e, 0x5f, 0x6b, 0x3b, 0x38, 0x8d,
|
||||
0x88, 0xac}, 0}
|
||||
p2pkScriptPubKey = &externalapi.ScriptPublicKey{[]byte{0x20, 0xb2, 0x52, 0xf0, 0x49, 0x85, 0x78, 0x03, 0x03,
|
||||
0xc8, 0x7d, 0xce, 0x51, 0x7f, 0xa8, 0x69, 0x0b,
|
||||
0x91, 0x95, 0xf4, 0xf3, 0x5c, 0x26, 0x73, 0x05,
|
||||
0x05, 0xa2, 0xee, 0xbc, 0x09, 0x38, 0x34, 0x3a, 0xac}, 0}
|
||||
shortScriptPubKey = &externalapi.ScriptPublicKey{[]byte{0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5,
|
||||
0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32,
|
||||
0x53, 0x90, 0x0e, 0x0a, 0x88, 0xac}, 0}
|
||||
@ -638,7 +631,7 @@ var sigScriptTests = []tstSigScript{
|
||||
{
|
||||
txout: &externalapi.DomainTransactionOutput{
|
||||
Value: coinbaseVal,
|
||||
ScriptPublicKey: p2pkhScriptPubKey,
|
||||
ScriptPublicKey: p2pkScriptPubKey,
|
||||
},
|
||||
sigscriptGenerates: true,
|
||||
inputValidates: true,
|
||||
@ -654,7 +647,7 @@ var sigScriptTests = []tstSigScript{
|
||||
{
|
||||
txout: &externalapi.DomainTransactionOutput{
|
||||
Value: coinbaseVal,
|
||||
ScriptPublicKey: p2pkhScriptPubKey,
|
||||
ScriptPublicKey: p2pkScriptPubKey,
|
||||
},
|
||||
sigscriptGenerates: true,
|
||||
inputValidates: true,
|
||||
@ -663,7 +656,7 @@ var sigScriptTests = []tstSigScript{
|
||||
{
|
||||
txout: &externalapi.DomainTransactionOutput{
|
||||
Value: coinbaseVal + fee,
|
||||
ScriptPublicKey: p2pkhScriptPubKey,
|
||||
ScriptPublicKey: p2pkScriptPubKey,
|
||||
},
|
||||
sigscriptGenerates: true,
|
||||
inputValidates: true,
|
||||
@ -679,7 +672,7 @@ var sigScriptTests = []tstSigScript{
|
||||
{
|
||||
txout: &externalapi.DomainTransactionOutput{
|
||||
Value: coinbaseVal,
|
||||
ScriptPublicKey: p2pkhScriptPubKey,
|
||||
ScriptPublicKey: p2pkScriptPubKey,
|
||||
},
|
||||
sigscriptGenerates: true,
|
||||
inputValidates: true,
|
||||
@ -695,7 +688,7 @@ var sigScriptTests = []tstSigScript{
|
||||
{
|
||||
txout: &externalapi.DomainTransactionOutput{
|
||||
Value: coinbaseVal,
|
||||
ScriptPublicKey: p2pkhScriptPubKey,
|
||||
ScriptPublicKey: p2pkScriptPubKey,
|
||||
},
|
||||
sigscriptGenerates: true,
|
||||
inputValidates: true,
|
||||
@ -711,7 +704,7 @@ var sigScriptTests = []tstSigScript{
|
||||
{
|
||||
txout: &externalapi.DomainTransactionOutput{
|
||||
Value: coinbaseVal,
|
||||
ScriptPublicKey: p2pkhScriptPubKey,
|
||||
ScriptPublicKey: p2pkScriptPubKey,
|
||||
},
|
||||
sigscriptGenerates: true,
|
||||
inputValidates: true,
|
||||
@ -727,7 +720,7 @@ var sigScriptTests = []tstSigScript{
|
||||
{
|
||||
txout: &externalapi.DomainTransactionOutput{
|
||||
Value: coinbaseVal,
|
||||
ScriptPublicKey: p2pkhScriptPubKey,
|
||||
ScriptPublicKey: p2pkScriptPubKey,
|
||||
},
|
||||
sigscriptGenerates: false,
|
||||
inputValidates: false,
|
||||
@ -743,7 +736,7 @@ var sigScriptTests = []tstSigScript{
|
||||
{
|
||||
txout: &externalapi.DomainTransactionOutput{
|
||||
Value: coinbaseVal,
|
||||
ScriptPublicKey: p2pkhScriptPubKey,
|
||||
ScriptPublicKey: p2pkScriptPubKey,
|
||||
},
|
||||
sigscriptGenerates: false,
|
||||
inputValidates: false,
|
||||
@ -759,7 +752,7 @@ var sigScriptTests = []tstSigScript{
|
||||
{
|
||||
txout: &externalapi.DomainTransactionOutput{
|
||||
Value: coinbaseVal,
|
||||
ScriptPublicKey: p2pkhScriptPubKey,
|
||||
ScriptPublicKey: p2pkScriptPubKey,
|
||||
},
|
||||
sigscriptGenerates: true,
|
||||
inputValidates: true,
|
||||
@ -768,7 +761,7 @@ var sigScriptTests = []tstSigScript{
|
||||
{
|
||||
txout: &externalapi.DomainTransactionOutput{
|
||||
Value: coinbaseVal + fee,
|
||||
ScriptPublicKey: p2pkhScriptPubKey,
|
||||
ScriptPublicKey: p2pkScriptPubKey,
|
||||
},
|
||||
sigscriptGenerates: true,
|
||||
inputValidates: true,
|
||||
@ -784,7 +777,7 @@ var sigScriptTests = []tstSigScript{
|
||||
{
|
||||
txout: &externalapi.DomainTransactionOutput{
|
||||
Value: coinbaseVal,
|
||||
ScriptPublicKey: p2pkhScriptPubKey,
|
||||
ScriptPublicKey: p2pkScriptPubKey,
|
||||
},
|
||||
sigscriptGenerates: true,
|
||||
inputValidates: true,
|
||||
@ -793,7 +786,7 @@ var sigScriptTests = []tstSigScript{
|
||||
{
|
||||
txout: &externalapi.DomainTransactionOutput{
|
||||
Value: coinbaseVal + fee,
|
||||
ScriptPublicKey: p2pkhScriptPubKey,
|
||||
ScriptPublicKey: p2pkScriptPubKey,
|
||||
},
|
||||
sigscriptGenerates: true,
|
||||
inputValidates: true,
|
||||
|
@ -21,7 +21,7 @@ type ScriptClass byte
|
||||
// Classes of script payment known about in the blockDAG.
|
||||
const (
|
||||
NonStandardTy ScriptClass = iota // None of the recognized forms.
|
||||
PubKeyHashTy // Pay pubkey hash.
|
||||
PubKeyTy // Pay to pubkey.
|
||||
ScriptHashTy // Pay to script hash.
|
||||
)
|
||||
|
||||
@ -29,7 +29,7 @@ const (
|
||||
// script class.
|
||||
var scriptClassToName = []string{
|
||||
NonStandardTy: "nonstandard",
|
||||
PubKeyHashTy: "pubkeyhash",
|
||||
PubKeyTy: "pubkey",
|
||||
ScriptHashTy: "scripthash",
|
||||
}
|
||||
|
||||
@ -43,23 +43,20 @@ func (t ScriptClass) String() string {
|
||||
return scriptClassToName[t]
|
||||
}
|
||||
|
||||
// isPubkeyHash returns true if the script passed is a pay-to-pubkey-hash
|
||||
// isPayToPubkey returns true if the script passed is a pay-to-pubkey
|
||||
// transaction, false otherwise.
|
||||
func isPubkeyHash(pops []parsedOpcode) bool {
|
||||
return len(pops) == 5 &&
|
||||
pops[0].opcode.value == OpDup &&
|
||||
pops[1].opcode.value == OpBlake2b &&
|
||||
pops[2].opcode.value == OpData32 &&
|
||||
pops[3].opcode.value == OpEqualVerify &&
|
||||
pops[4].opcode.value == OpCheckSig
|
||||
func isPayToPubkey(pops []parsedOpcode) bool {
|
||||
return len(pops) == 2 &&
|
||||
pops[0].opcode.value == OpData32 &&
|
||||
pops[1].opcode.value == OpCheckSig
|
||||
|
||||
}
|
||||
|
||||
// scriptType returns the type of the script being inspected from the known
|
||||
// standard types.
|
||||
func typeOfScript(pops []parsedOpcode) ScriptClass {
|
||||
if isPubkeyHash(pops) {
|
||||
return PubKeyHashTy
|
||||
if isPayToPubkey(pops) {
|
||||
return PubKeyTy
|
||||
} else if isScriptHash(pops) {
|
||||
return ScriptHashTy
|
||||
}
|
||||
@ -85,8 +82,8 @@ func GetScriptClass(script []byte) ScriptClass {
|
||||
func expectedInputs(pops []parsedOpcode, class ScriptClass) int {
|
||||
switch class {
|
||||
|
||||
case PubKeyHashTy:
|
||||
return 2
|
||||
case PubKeyTy:
|
||||
return 1
|
||||
|
||||
case ScriptHashTy:
|
||||
// Not including script. That is handled by the caller.
|
||||
@ -169,12 +166,13 @@ func CalcScriptInfo(sigScript, scriptPubKey []byte, isP2SH bool) (*ScriptInfo, e
|
||||
return si, nil
|
||||
}
|
||||
|
||||
// payToPubKeyHashScript creates a new script to pay a transaction
|
||||
// output to a 20-byte pubkey hash. It is expected that the input is a valid
|
||||
// payToPubKeyScript creates a new script to pay a transaction
|
||||
// output to a 32-byte pubkey. It is expected that the input is a valid
|
||||
// hash.
|
||||
func payToPubKeyHashScript(pubKeyHash []byte) ([]byte, error) {
|
||||
return NewScriptBuilder().AddOp(OpDup).AddOp(OpBlake2b).
|
||||
AddData(pubKeyHash).AddOp(OpEqualVerify).AddOp(OpCheckSig).
|
||||
func payToPubKeyScript(pubKey []byte) ([]byte, error) {
|
||||
return NewScriptBuilder().
|
||||
AddData(pubKey).
|
||||
AddOp(OpCheckSig).
|
||||
Script()
|
||||
}
|
||||
|
||||
@ -190,12 +188,12 @@ func payToScriptHashScript(scriptHash []byte) ([]byte, error) {
|
||||
func PayToAddrScript(addr util.Address) (*externalapi.ScriptPublicKey, error) {
|
||||
const nilAddrErrStr = "unable to generate payment script for nil address"
|
||||
switch addr := addr.(type) {
|
||||
case *util.AddressPubKeyHash:
|
||||
case *util.AddressPublicKey:
|
||||
if addr == nil {
|
||||
return nil, scriptError(ErrUnsupportedAddress,
|
||||
nilAddrErrStr)
|
||||
}
|
||||
script, err := payToPubKeyHashScript(addr.ScriptAddress())
|
||||
script, err := payToPubKeyScript(addr.ScriptAddress())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -276,12 +274,12 @@ func ExtractScriptPubKeyAddress(scriptPubKey *externalapi.ScriptPublicKey, dagPa
|
||||
|
||||
scriptClass := typeOfScript(pops)
|
||||
switch scriptClass {
|
||||
case PubKeyHashTy:
|
||||
// A pay-to-pubkey-hash script is of the form:
|
||||
// OP_DUP OP_BLAKE2B <hash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
// Therefore the pubkey hash is the 3rd item on the stack.
|
||||
// If the pubkey hash is invalid for some reason, return a nil address.
|
||||
addr, err := util.NewAddressPubKeyHash(pops[2].data,
|
||||
case PubKeyTy:
|
||||
// A pay-to-pubkey script is of the form:
|
||||
// <pubkey> OP_CHECKSIG
|
||||
// Therefore the pubkey is the first item on the stack.
|
||||
// If the pubkey is invalid for some reason, return a nil address.
|
||||
addr, err := util.NewAddressPublicKey(pops[0].data,
|
||||
dagParams.Prefix)
|
||||
if err != nil {
|
||||
return scriptClass, nil, nil
|
||||
|
@ -28,14 +28,14 @@ func mustParseShortForm(script string, version uint16) []byte {
|
||||
return s
|
||||
}
|
||||
|
||||
// newAddressPubKeyHash returns a new util.AddressPubKeyHash from the
|
||||
// provided hash. It panics if an error occurs. This is only used in the tests
|
||||
// newAddressPublicKey returns a new util.AddressPublicKey from the
|
||||
// provided public key. It panics if an error occurs. This is only used in the tests
|
||||
// as a helper since the only way it can fail is if there is an error in the
|
||||
// test source code.
|
||||
func newAddressPubKeyHash(pkHash []byte) util.Address {
|
||||
addr, err := util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixKaspa)
|
||||
func newAddressPublicKey(publicKey []byte) util.Address {
|
||||
addr, err := util.NewAddressPublicKey(publicKey, util.Bech32PrefixKaspa)
|
||||
if err != nil {
|
||||
panic("invalid public key hash in test source")
|
||||
panic("invalid public key in test source")
|
||||
}
|
||||
|
||||
return addr
|
||||
@ -67,15 +67,13 @@ func TestExtractScriptPubKeyAddrs(t *testing.T) {
|
||||
class ScriptClass
|
||||
}{
|
||||
{
|
||||
name: "standard p2pkh",
|
||||
name: "standard p2pk",
|
||||
script: &externalapi.ScriptPublicKey{
|
||||
Script: hexToBytes("76aa20ad06dd6ddee55cbca9a9e3713bd" +
|
||||
"7587509a30564ad06dd6ddee55cbca9a9e37188ac"),
|
||||
Script: hexToBytes("202454a285d8566b0cb2792919536ee0f1b6f69b58ba59e9850ecbc91eef722daeac"),
|
||||
Version: 0,
|
||||
},
|
||||
addr: newAddressPubKeyHash(hexToBytes("ad06dd6ddee5" +
|
||||
"5cbca9a9e3713bd7587509a30564ad06dd6ddee55cbca9a9e371")),
|
||||
class: PubKeyHashTy,
|
||||
addr: newAddressPublicKey(hexToBytes("2454a285d8566b0cb2792919536ee0f1b6f69b58ba59e9850ecbc91eef722dae")),
|
||||
class: PubKeyTy,
|
||||
},
|
||||
{
|
||||
name: "standard p2sh",
|
||||
@ -216,8 +214,8 @@ func TestCalcScriptInfo(t *testing.T) {
|
||||
{
|
||||
// Invented scripts, the hashes do not match
|
||||
name: "p2sh standard script",
|
||||
sigScript: "1 81 DATA_37 DUP BLAKE2B DATA_32 0x010203" +
|
||||
"0405060708090a0b0c0d0e0f1011121314fe441065b6532231de2fac56 EQUALVERIFY " +
|
||||
sigScript: "1 81 DATA_34 DATA_32 0x010203" +
|
||||
"0405060708090a0b0c0d0e0f1011121314fe441065b6532231de2fac56 " +
|
||||
"CHECKSIG",
|
||||
scriptPubKey: "BLAKE2B DATA_32 0xfe441065b6532231de2fac56" +
|
||||
"3152205ec4f59c74fe441065b6532231de2fac56 EQUAL",
|
||||
@ -225,7 +223,7 @@ func TestCalcScriptInfo(t *testing.T) {
|
||||
scriptInfo: ScriptInfo{
|
||||
ScriptPubKeyClass: ScriptHashTy,
|
||||
NumInputs: 3,
|
||||
ExpectedInputs: 3, // nonstandard p2sh.
|
||||
ExpectedInputs: 2, // nonstandard p2sh.
|
||||
SigOps: 1,
|
||||
},
|
||||
},
|
||||
@ -303,10 +301,10 @@ func (b *bogusAddress) Prefix() util.Bech32Prefix {
|
||||
func TestPayToAddrScript(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p2pkhMain, err := util.NewAddressPubKeyHash(hexToBytes("e34cce70c86"+
|
||||
p2pkMain, err := util.NewAddressPublicKey(hexToBytes("e34cce70c86"+
|
||||
"373273efcc54ce7d2a491bb4a0e84e34cce70c86373273efcc54c"), util.Bech32PrefixKaspa)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create public key hash address: %v", err)
|
||||
t.Fatalf("Unable to create public key address: %v", err)
|
||||
}
|
||||
|
||||
p2shMain, err := util.NewAddressScriptHashFromHash(hexToBytes("e8c300"+
|
||||
@ -325,11 +323,11 @@ func TestPayToAddrScript(t *testing.T) {
|
||||
expectedVersion uint16
|
||||
err error
|
||||
}{
|
||||
// pay-to-pubkey-hash address on mainnet
|
||||
// pay-to-pubkey address on mainnet
|
||||
{
|
||||
p2pkhMain,
|
||||
"DUP BLAKE2B DATA_32 0xe34cce70c86373273efcc54ce7d2a4" +
|
||||
"91bb4a0e84e34cce70c86373273efcc54c EQUALVERIFY CHECKSIG",
|
||||
p2pkMain,
|
||||
"DATA_32 0xe34cce70c86373273efcc54ce7d2a4" +
|
||||
"91bb4a0e84e34cce70c86373273efcc54c CHECKSIG",
|
||||
0,
|
||||
nil,
|
||||
},
|
||||
@ -343,7 +341,7 @@ func TestPayToAddrScript(t *testing.T) {
|
||||
},
|
||||
|
||||
// Supported address types with nil pointers.
|
||||
{(*util.AddressPubKeyHash)(nil), "", 0, errUnsupportedAddress},
|
||||
{(*util.AddressPublicKey)(nil), "", 0, errUnsupportedAddress},
|
||||
{(*util.AddressScriptHash)(nil), "", 0, errUnsupportedAddress},
|
||||
|
||||
// Unsupported address type.
|
||||
@ -393,16 +391,14 @@ var scriptClassTests = []struct {
|
||||
// p2pk
|
||||
{
|
||||
name: "Pay Pubkey",
|
||||
script: "DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e" +
|
||||
"97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e16" +
|
||||
"0bfa9b8b64f9d4c03f999b8643f656b412a3 CHECKSIG",
|
||||
class: NonStandardTy,
|
||||
script: "DATA_32 0x89ac24ea10bb751af4939623ccc5e550d96842b64e8fca0f63e94b4373fd555e CHECKSIG",
|
||||
class: PubKeyTy,
|
||||
},
|
||||
{
|
||||
name: "Pay PubkeyHash",
|
||||
script: "DUP BLAKE2B DATA_32 0x660d4ef3a743e3e696ad990364e55543e3e696ad990364e555e555" +
|
||||
"c271ad504b EQUALVERIFY CHECKSIG",
|
||||
class: PubKeyHashTy,
|
||||
class: NonStandardTy,
|
||||
},
|
||||
// mutlisig
|
||||
{
|
||||
@ -513,9 +509,9 @@ func TestStringifyClass(t *testing.T) {
|
||||
stringed: "nonstandard",
|
||||
},
|
||||
{
|
||||
name: "pubkeyhash",
|
||||
class: PubKeyHashTy,
|
||||
stringed: "pubkeyhash",
|
||||
name: "pubkey",
|
||||
class: PubKeyTy,
|
||||
stringed: "pubkey",
|
||||
},
|
||||
{
|
||||
name: "scripthash",
|
||||
|
@ -38,8 +38,8 @@ func main() {
|
||||
// later...
|
||||
|
||||
// Create and print new payment address, specific to the active network.
|
||||
pubKeyHash := make([]byte, 20)
|
||||
addr, err := util.NewAddressPubKeyHash(pubKeyHash, dagParams)
|
||||
pubKey := make([]byte, 32)
|
||||
addr, err := util.NewAddressPubKey(pubKey, dagParams)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -46,8 +46,8 @@ variable (either directly, or hidden in a library call).
|
||||
// later...
|
||||
|
||||
// Create and print new payment address, specific to the active network.
|
||||
pubKeyHash := make([]byte, 20)
|
||||
addr, err := util.NewAddressPubKeyHash(pubKeyHash, dagParams)
|
||||
pubKey := make([]byte, 32)
|
||||
addr, err := util.NewAddressPubKey(pubKey, dagParams)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -127,43 +127,18 @@ func isDust(txOut *consensusexternalapi.DomainTransactionOutput, minRelayTxFee u
|
||||
// input script to redeem it. Since there is no input script
|
||||
// to redeem it yet, use the minimum size of a typical input script.
|
||||
//
|
||||
// Pay-to-pubkey-hash bytes breakdown:
|
||||
//
|
||||
// Output to hash (34 bytes):
|
||||
// 8 value, 1 script len, 25 script [1 OP_DUP, 1 OP_HASH_160,
|
||||
// 1 OP_DATA_20, 20 hash, 1 OP_EQUALVERIFY, 1 OP_CHECKSIG]
|
||||
//
|
||||
// Input with compressed pubkey (148 bytes):
|
||||
// 36 prev outpoint, 1 script len, 107 script [1 OP_DATA_72, 72 sig,
|
||||
// 1 OP_DATA_33, 33 compressed pubkey], 4 sequence
|
||||
//
|
||||
// Input with uncompressed pubkey (180 bytes):
|
||||
// 36 prev outpoint, 1 script len, 139 script [1 OP_DATA_72, 72 sig,
|
||||
// 1 OP_DATA_65, 65 compressed pubkey], 4 sequence
|
||||
//
|
||||
// Pay-to-pubkey bytes breakdown:
|
||||
//
|
||||
// Output to compressed pubkey (44 bytes):
|
||||
// 8 value, 1 script len, 35 script [1 OP_DATA_33,
|
||||
// 33 compressed pubkey, 1 OP_CHECKSIG]
|
||||
// Output to pubkey (43 bytes):
|
||||
// 8 value, 1 script len, 34 script [1 OP_DATA_32,
|
||||
// 32 pubkey, 1 OP_CHECKSIG]
|
||||
//
|
||||
// Output to uncompressed pubkey (76 bytes):
|
||||
// 8 value, 1 script len, 67 script [1 OP_DATA_65, 65 pubkey,
|
||||
// 1 OP_CHECKSIG]
|
||||
// Input (105 bytes):
|
||||
// 36 prev outpoint, 1 script len, 64 script [1 OP_DATA_64,
|
||||
// 64 sig], 4 sequence
|
||||
//
|
||||
// Input (114 bytes):
|
||||
// 36 prev outpoint, 1 script len, 73 script [1 OP_DATA_72,
|
||||
// 72 sig], 4 sequence
|
||||
//
|
||||
// Theoretically this could examine the script type of the output script
|
||||
// and use a different size for the typical input script size for
|
||||
// pay-to-pubkey vs pay-to-pubkey-hash inputs per the above breakdowns,
|
||||
// but the only combination which is less than the value chosen is
|
||||
// a pay-to-pubkey script with a compressed pubkey, which is not very
|
||||
// common.
|
||||
//
|
||||
// The most common scripts are pay-to-pubkey-hash, and as per the above
|
||||
// breakdown, the minimum size of a p2pkh input script is 148 bytes. So
|
||||
// The most common scripts are pay-to-pubkey, and as per the above
|
||||
// breakdown, the minimum size of a p2pk input script is 148 bytes. So
|
||||
// that figure is used.
|
||||
totalSize := estimatedsize.TransactionOutputEstimatedSerializedSize(txOut) + 148
|
||||
|
||||
@ -172,7 +147,7 @@ func isDust(txOut *consensusexternalapi.DomainTransactionOutput, minRelayTxFee u
|
||||
// minFreeTxRelayFee is in sompi/KB, so multiply by 1000 to
|
||||
// convert to bytes.
|
||||
//
|
||||
// Using the typical values for a pay-to-pubkey-hash transaction from
|
||||
// Using the typical values for a pay-to-pubkey transaction from
|
||||
// the breakdown above and the default minimum free transaction relay
|
||||
// fee of 1000, this equates to values less than 546 sompi being
|
||||
// considered dust.
|
||||
|
@ -179,9 +179,9 @@ func TestCheckTransactionStandard(t *testing.T) {
|
||||
Sequence: constants.MaxTxInSequenceNum,
|
||||
}
|
||||
addrHash := [32]byte{0x01}
|
||||
addr, err := util.NewAddressPubKeyHash(addrHash[:], util.Bech32PrefixKaspaTest)
|
||||
addr, err := util.NewAddressPublicKey(addrHash[:], util.Bech32PrefixKaspaTest)
|
||||
if err != nil {
|
||||
t.Fatalf("NewAddressPubKeyHash: unexpected error: %v", err)
|
||||
t.Fatalf("NewAddressPublicKey: unexpected error: %v", err)
|
||||
}
|
||||
dummyScriptPublicKey, err := txscript.PayToAddrScript(addr)
|
||||
if err != nil {
|
||||
@ -200,7 +200,7 @@ func TestCheckTransactionStandard(t *testing.T) {
|
||||
code RejectCode
|
||||
}{
|
||||
{
|
||||
name: "Typical pay-to-pubkey-hash transaction",
|
||||
name: "Typical pay-to-pubkey transaction",
|
||||
tx: consensusexternalapi.DomainTransaction{Version: 0, Inputs: []*consensusexternalapi.DomainTransactionInput{&dummyTxIn}, Outputs: []*consensusexternalapi.DomainTransactionOutput{&dummyTxOut}},
|
||||
height: 300000,
|
||||
isStandard: true,
|
||||
|
@ -15,7 +15,6 @@ import (
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
"github.com/kaspanet/kaspad/util/panics"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/crypto/blake2b"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -178,8 +177,8 @@ func useDirOrCreateTemp(dataDir, tempName string) (string, error) {
|
||||
}
|
||||
|
||||
func mineOnTips(client *rpc.Client) (appmessage.RejectReason, error) {
|
||||
fakePublicKeyHash := make([]byte, blake2b.Size256)
|
||||
addr, err := util.NewAddressPubKeyHash(fakePublicKeyHash, activeConfig().NetParams().Prefix)
|
||||
fakePublicKey := make([]byte, util.PublicKeySize)
|
||||
addr, err := util.NewAddressPublicKey(fakePublicKey, activeConfig().NetParams().Prefix)
|
||||
if err != nil {
|
||||
return appmessage.RejectReasonNone, err
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ func generateAddress() (util.Address, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return util.NewAddressPubKeyHashFromPublicKey(pubKeySerialized[:], activeConfig().ActiveNetParams.Prefix)
|
||||
return util.NewAddressPublicKey(pubKeySerialized[:], activeConfig().ActiveNetParams.Prefix)
|
||||
}
|
||||
|
||||
func areTipsAreEqual(resultA, resultB *appmessage.GetBlockDAGInfoResponseMessage) bool {
|
||||
|
@ -18,14 +18,14 @@ const (
|
||||
rpcAddress2 = "127.0.0.1:12346"
|
||||
rpcAddress3 = "127.0.0.1:12347"
|
||||
|
||||
miningAddress1 = "kaspasim:qr79e37hxdgkn4xjjmfxvqvayc5gsmsql2660d08u9ej9vnc8lzcywr265u64"
|
||||
miningAddress1PrivateKey = "0ec5d7308f65717f3f0c3e4d962d73056c1c255a16593b3989589281b51ad5bc"
|
||||
miningAddress1 = "kaspasim:qqqqnc0pxg7qw3qkc7l6sge8kfhsvvyt7mkw8uamtndqup27ftnd6c769gn66"
|
||||
miningAddress1PrivateKey = "0d81045b0deb2af36a25403c2154c87aa82d89dd337b575bae27ce7f5de53cee"
|
||||
|
||||
miningAddress2 = "kaspasim:qpvr825ypd2fzq779yl83zvte2r4wlgxwra625rgthk9jj96d4cxgsegwryhg"
|
||||
miningAddress2PrivateKey = "2a2e99d4a5c3e6d4add69e7baf66b9c7a2f17e74fad86cbd36a3a6815cecc10e"
|
||||
miningAddress2 = "kaspasim:qqqqnc0pxg7qw3qkc7l6sge8kfhsvvyt7mkw8uamtndqup27ftnd6c769gn66"
|
||||
miningAddress2PrivateKey = "0d81045b0deb2af36a25403c2154c87aa82d89dd337b575bae27ce7f5de53cee"
|
||||
|
||||
miningAddress3 = "kaspasim:qpvr825ypd2fzq779yl83zvte2r4wlgxwra625rgthk9jj96d4cxgsegwryhg"
|
||||
miningAddress3PrivateKey = "2a2e99d4a5c3e6d4add69e7baf66b9c7a2f17e74fad86cbd36a3a6815cecc10e"
|
||||
miningAddress3 = "kaspasim:qqq754f2gdcjcnykwuwwr60c82rh5u6mxxe7yqxljnrxz9fu0h95kduq9ezng"
|
||||
miningAddress3PrivateKey = "f6c8f31fd359cbb97007034780bc4021f6ad01c6bc10499b79849efd4cc7ca39"
|
||||
|
||||
defaultTimeout = 10 * time.Second
|
||||
)
|
||||
|
@ -20,8 +20,8 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
// PubKeyHash addresses always have the version byte set to 0.
|
||||
pubKeyHashAddrID = 0x00
|
||||
// PubKey addresses always have the version byte set to 0.
|
||||
pubKeyAddrID = 0x00
|
||||
|
||||
// ScriptHash addresses always have the version byte set to 8.
|
||||
scriptHashAddrID = 0x08
|
||||
@ -79,16 +79,16 @@ func (prefix Bech32Prefix) String() string {
|
||||
}
|
||||
|
||||
// encodeAddress returns a human-readable payment address given a network prefix
|
||||
// and a blake2b hash which encodes the kaspa network and address type. It is used
|
||||
// in both pay-to-pubkey-hash (P2PKH) and pay-to-script-hash (P2SH) address
|
||||
// and a payload which encodes the kaspa network and address type. It is used
|
||||
// in both pay-to-pubkey (P2PK) and pay-to-script-hash (P2SH) address
|
||||
// encoding.
|
||||
func encodeAddress(prefix Bech32Prefix, hash256 []byte, version byte) string {
|
||||
return bech32.Encode(prefix.String(), hash256[:blake2b.Size256], version)
|
||||
func encodeAddress(prefix Bech32Prefix, payload []byte, version byte) string {
|
||||
return bech32.Encode(prefix.String(), payload, version)
|
||||
}
|
||||
|
||||
// Address is an interface type for any type of destination a transaction
|
||||
// output may spend to. This includes pay-to-pubkey (P2PK), pay-to-pubkey-hash
|
||||
// (P2PKH), and pay-to-script-hash (P2SH). Address is designed to be generic
|
||||
// output may spend to. This includes pay-to-pubkey (P2PK)
|
||||
// and pay-to-script-hash (P2SH). Address is designed to be generic
|
||||
// enough that other kinds of addresses may be added in the future without
|
||||
// changing the decoding and encoding API.
|
||||
type Address interface {
|
||||
@ -98,7 +98,7 @@ type Address interface {
|
||||
// Please note that String differs subtly from EncodeAddress: String
|
||||
// will return the value as a string without any conversion, while
|
||||
// EncodeAddress may convert destination types (for example,
|
||||
// converting pubkeys to P2PKH addresses) before encoding as a
|
||||
// converting pubkeys to P2PK addresses) before encoding as a
|
||||
// payment address string.
|
||||
String() string
|
||||
|
||||
@ -139,95 +139,79 @@ func DecodeAddress(addr string, expectedPrefix Bech32Prefix) (Address, error) {
|
||||
prefix)
|
||||
}
|
||||
|
||||
// Switch on decoded length to determine the type.
|
||||
switch len(decoded) {
|
||||
case blake2b.Size256: // P2PKH or P2SH
|
||||
switch version {
|
||||
case pubKeyHashAddrID:
|
||||
return newAddressPubKeyHash(prefix, decoded)
|
||||
case pubKeyAddrID:
|
||||
return newAddressPubKey(prefix, decoded)
|
||||
case scriptHashAddrID:
|
||||
return newAddressScriptHashFromHash(prefix, decoded)
|
||||
default:
|
||||
return nil, ErrUnknownAddressType
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("decoded address is of unknown size")
|
||||
}
|
||||
}
|
||||
|
||||
// AddressPubKeyHash is an Address for a pay-to-pubkey-hash (P2PKH)
|
||||
// PublicKeySize is the public key size for a schnorr public key
|
||||
const PublicKeySize = 32
|
||||
|
||||
// AddressPublicKey is an Address for a pay-to-pubkey (P2PK)
|
||||
// transaction.
|
||||
type AddressPubKeyHash struct {
|
||||
type AddressPublicKey struct {
|
||||
prefix Bech32Prefix
|
||||
hash [blake2b.Size256]byte
|
||||
publicKey [PublicKeySize]byte
|
||||
}
|
||||
|
||||
// NewAddressPubKeyHashFromPublicKey returns a new AddressPubKeyHash from given public key
|
||||
func NewAddressPubKeyHashFromPublicKey(publicKey []byte, prefix Bech32Prefix) (*AddressPubKeyHash, error) {
|
||||
pkHash := HashBlake2b(publicKey)
|
||||
return newAddressPubKeyHash(prefix, pkHash)
|
||||
}
|
||||
|
||||
// NewAddressPubKeyHash returns a new AddressPubKeyHash. pkHash mustbe 20
|
||||
// NewAddressPublicKey returns a new AddressPublicKey. publicKey must be 32
|
||||
// bytes.
|
||||
func NewAddressPubKeyHash(pkHash []byte, prefix Bech32Prefix) (*AddressPubKeyHash, error) {
|
||||
return newAddressPubKeyHash(prefix, pkHash)
|
||||
func NewAddressPublicKey(publicKey []byte, prefix Bech32Prefix) (*AddressPublicKey, error) {
|
||||
return newAddressPubKey(prefix, publicKey)
|
||||
}
|
||||
|
||||
// newAddressPubKeyHash is the internal API to create a pubkey hash address
|
||||
// newAddressPubKey is the internal API to create a pubkey address
|
||||
// with a known leading identifier byte for a network, rather than looking
|
||||
// it up through its parameters. This is useful when creating a new address
|
||||
// structure from a string encoding where the identifier byte is already
|
||||
// known.
|
||||
func newAddressPubKeyHash(prefix Bech32Prefix, pkHash []byte) (*AddressPubKeyHash, error) {
|
||||
// Check for a valid pubkey hash length.
|
||||
if len(pkHash) != blake2b.Size256 {
|
||||
return nil, errors.Errorf("pkHash must be %d bytes", blake2b.Size256)
|
||||
func newAddressPubKey(prefix Bech32Prefix, publicKey []byte) (*AddressPublicKey, error) {
|
||||
// Check for a valid pubkey length.
|
||||
if len(publicKey) != PublicKeySize {
|
||||
return nil, errors.Errorf("publicKey must be %d bytes", PublicKeySize)
|
||||
}
|
||||
|
||||
addr := &AddressPubKeyHash{prefix: prefix}
|
||||
copy(addr.hash[:], pkHash)
|
||||
addr := &AddressPublicKey{prefix: prefix}
|
||||
copy(addr.publicKey[:], publicKey)
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
// EncodeAddress returns the string encoding of a pay-to-pubkey-hash
|
||||
// EncodeAddress returns the string encoding of a pay-to-pubkey
|
||||
// address. Part of the Address interface.
|
||||
func (a *AddressPubKeyHash) EncodeAddress() string {
|
||||
return encodeAddress(a.prefix, a.hash[:], pubKeyHashAddrID)
|
||||
func (a *AddressPublicKey) EncodeAddress() string {
|
||||
return encodeAddress(a.prefix, a.publicKey[:], pubKeyAddrID)
|
||||
}
|
||||
|
||||
// ScriptAddress returns the bytes to be included in a txout script to pay
|
||||
// to a pubkey hash. Part of the Address interface.
|
||||
func (a *AddressPubKeyHash) ScriptAddress() []byte {
|
||||
return a.hash[:]
|
||||
// to a pubkey. Part of the Address interface.
|
||||
func (a *AddressPublicKey) ScriptAddress() []byte {
|
||||
return a.publicKey[:]
|
||||
}
|
||||
|
||||
// IsForPrefix returns whether or not the pay-to-pubkey-hash address is associated
|
||||
// IsForPrefix returns whether or not the pay-to-pubkey address is associated
|
||||
// with the passed kaspa network.
|
||||
func (a *AddressPubKeyHash) IsForPrefix(prefix Bech32Prefix) bool {
|
||||
func (a *AddressPublicKey) IsForPrefix(prefix Bech32Prefix) bool {
|
||||
return a.prefix == prefix
|
||||
}
|
||||
|
||||
// Prefix returns the prefix for this address
|
||||
func (a *AddressPubKeyHash) Prefix() Bech32Prefix {
|
||||
func (a *AddressPublicKey) Prefix() Bech32Prefix {
|
||||
return a.prefix
|
||||
}
|
||||
|
||||
// String returns a human-readable string for the pay-to-pubkey-hash address.
|
||||
// String returns a human-readable string for the pay-to-pubkey address.
|
||||
// This is equivalent to calling EncodeAddress, but is provided so the type can
|
||||
// be used as a fmt.Stringer.
|
||||
func (a *AddressPubKeyHash) String() string {
|
||||
func (a *AddressPublicKey) String() string {
|
||||
return a.EncodeAddress()
|
||||
}
|
||||
|
||||
// HashBlake2b returns the underlying array of the pubkey hash. This can be useful
|
||||
// when an array is more appropiate than a slice (for example, when used as map
|
||||
// keys).
|
||||
func (a *AddressPubKeyHash) HashBlake2b() *[blake2b.Size256]byte {
|
||||
return &a.hash
|
||||
}
|
||||
|
||||
// AddressScriptHash is an Address for a pay-to-script-hash (P2SH)
|
||||
// AddressScriptHash is an Address for a pay-to-script-publicKey (P2SH)
|
||||
// transaction.
|
||||
type AddressScriptHash struct {
|
||||
prefix Bech32Prefix
|
||||
|
@ -26,99 +26,99 @@ func TestAddresses(t *testing.T) {
|
||||
passedPrefix util.Bech32Prefix
|
||||
expectedPrefix util.Bech32Prefix
|
||||
}{
|
||||
// Positive P2PKH tests.
|
||||
// Positive P2PK tests.
|
||||
{
|
||||
name: "mainnet p2pkh",
|
||||
name: "mainnet p2pk",
|
||||
addr: "kaspa:qr35ennsep3hxfe7lnz5ee7j5jgmkjswsn35ennsep3hxfe7ln35cdv0dy335",
|
||||
encoded: "kaspa:qr35ennsep3hxfe7lnz5ee7j5jgmkjswsn35ennsep3hxfe7ln35cdv0dy335",
|
||||
valid: true,
|
||||
result: util.TstAddressPubKeyHash(
|
||||
result: util.TstAddressPubKey(
|
||||
util.Bech32PrefixKaspa,
|
||||
[blake2b.Size256]byte{
|
||||
[util.PublicKeySize]byte{
|
||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||
0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84,
|
||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||
0xe3, 0x4c,
|
||||
}),
|
||||
f: func() (util.Address, error) {
|
||||
pkHash := []byte{
|
||||
publicKey := []byte{
|
||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||
0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84,
|
||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||
0xe3, 0x4c}
|
||||
return util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixKaspa)
|
||||
return util.NewAddressPublicKey(publicKey, util.Bech32PrefixKaspa)
|
||||
},
|
||||
passedPrefix: util.Bech32PrefixUnknown,
|
||||
expectedPrefix: util.Bech32PrefixKaspa,
|
||||
},
|
||||
{
|
||||
name: "mainnet p2pkh 2",
|
||||
name: "mainnet p2pk 2",
|
||||
addr: "kaspa:qq80qvqs0lfxuzmt7sz3909ze6camq9d4t35ennsep3hxfe7ln35cvfqgz3z8",
|
||||
encoded: "kaspa:qq80qvqs0lfxuzmt7sz3909ze6camq9d4t35ennsep3hxfe7ln35cvfqgz3z8",
|
||||
valid: true,
|
||||
result: util.TstAddressPubKeyHash(
|
||||
result: util.TstAddressPubKey(
|
||||
util.Bech32PrefixKaspa,
|
||||
[blake2b.Size256]byte{
|
||||
[util.PublicKeySize]byte{
|
||||
0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4,
|
||||
0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa,
|
||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||
0xe3, 0x4c,
|
||||
}),
|
||||
f: func() (util.Address, error) {
|
||||
pkHash := []byte{
|
||||
publicKey := []byte{
|
||||
0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4,
|
||||
0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa,
|
||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||
0xe3, 0x4c,
|
||||
}
|
||||
return util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixKaspa)
|
||||
return util.NewAddressPublicKey(publicKey, util.Bech32PrefixKaspa)
|
||||
},
|
||||
passedPrefix: util.Bech32PrefixKaspa,
|
||||
expectedPrefix: util.Bech32PrefixKaspa,
|
||||
},
|
||||
{
|
||||
name: "testnet p2pkh",
|
||||
name: "testnet p2pk",
|
||||
addr: "kaspatest:qputx94qseratdmjs0j395mq8u03er0x3l35ennsep3hxfe7ln35ckquw528z",
|
||||
encoded: "kaspatest:qputx94qseratdmjs0j395mq8u03er0x3l35ennsep3hxfe7ln35ckquw528z",
|
||||
valid: true,
|
||||
result: util.TstAddressPubKeyHash(
|
||||
result: util.TstAddressPubKey(
|
||||
util.Bech32PrefixKaspaTest,
|
||||
[blake2b.Size256]byte{
|
||||
[util.PublicKeySize]byte{
|
||||
0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83,
|
||||
0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f,
|
||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||
0xe3, 0x4c,
|
||||
}),
|
||||
f: func() (util.Address, error) {
|
||||
pkHash := []byte{
|
||||
publicKey := []byte{
|
||||
0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83,
|
||||
0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f,
|
||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||
0xe3, 0x4c,
|
||||
}
|
||||
return util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixKaspaTest)
|
||||
return util.NewAddressPublicKey(publicKey, util.Bech32PrefixKaspaTest)
|
||||
},
|
||||
passedPrefix: util.Bech32PrefixKaspaTest,
|
||||
expectedPrefix: util.Bech32PrefixKaspaTest,
|
||||
},
|
||||
|
||||
// Negative P2PKH tests.
|
||||
// Negative P2PK tests.
|
||||
{
|
||||
name: "p2pkh wrong hash length",
|
||||
name: "p2pk wrong public key length",
|
||||
addr: "",
|
||||
valid: false,
|
||||
f: func() (util.Address, error) {
|
||||
pkHash := []byte{
|
||||
publicKey := []byte{
|
||||
0x00, 0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b,
|
||||
0xf4, 0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad,
|
||||
0xaa}
|
||||
return util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixKaspa)
|
||||
return util.NewAddressPublicKey(publicKey, util.Bech32PrefixKaspa)
|
||||
},
|
||||
passedPrefix: util.Bech32PrefixKaspa,
|
||||
expectedPrefix: util.Bech32PrefixKaspa,
|
||||
},
|
||||
{
|
||||
name: "p2pkh bad checksum",
|
||||
name: "p2pk bad checksum",
|
||||
addr: "kaspa:qr35ennsep3hxfe7lnz5ee7j5jgmkjswss74as46gx",
|
||||
valid: false,
|
||||
passedPrefix: util.Bech32PrefixKaspa,
|
||||
@ -270,23 +270,22 @@ func TestAddresses(t *testing.T) {
|
||||
// Perform type-specific calculations.
|
||||
var saddr []byte
|
||||
switch decoded.(type) {
|
||||
case *util.AddressPubKeyHash:
|
||||
saddr = util.TstAddressSAddr(encoded)
|
||||
case *util.AddressPublicKey:
|
||||
saddr = util.TstAddressSAddrP2PK(encoded)
|
||||
|
||||
case *util.AddressScriptHash:
|
||||
saddr = util.TstAddressSAddr(encoded)
|
||||
saddr = util.TstAddressSAddrP2SH(encoded)
|
||||
}
|
||||
|
||||
// Check script address, as well as the HashBlake2b method for P2PKH and
|
||||
// P2SH addresses.
|
||||
// Check script address, as well as the HashBlake2b method for P2SH addresses.
|
||||
if !bytes.Equal(saddr, decoded.ScriptAddress()) {
|
||||
t.Errorf("%v: script addresses do not match:\n%x != \n%x",
|
||||
test.name, saddr, decoded.ScriptAddress())
|
||||
return
|
||||
}
|
||||
switch a := decoded.(type) {
|
||||
case *util.AddressPubKeyHash:
|
||||
if h := a.HashBlake2b()[:]; !bytes.Equal(saddr, h) {
|
||||
case *util.AddressPublicKey:
|
||||
if h := a.ScriptAddress()[:]; !bytes.Equal(saddr, h) {
|
||||
t.Errorf("%v: hashes do not match:\n%x != \n%x",
|
||||
test.name, saddr, h)
|
||||
return
|
||||
@ -357,7 +356,7 @@ func TestDecodeAddressErrorConditions(t *testing.T) {
|
||||
{
|
||||
"kaspasim:raskzcg58mth0an",
|
||||
util.Bech32PrefixKaspaSim,
|
||||
"decoded address is of unknown size",
|
||||
"unknown address type",
|
||||
},
|
||||
{
|
||||
"kaspatest:qqq65mvpxcmajeq44n2n8vfn6u9f8l4zsy0xez0tzw",
|
||||
|
@ -18,14 +18,14 @@ expensive hashing operations.
|
||||
Address Overview
|
||||
|
||||
The Address interface provides an abstraction for a kaspa address. While the
|
||||
most common type is a pay-to-pubkey-hash, kaspa already supports others and
|
||||
most common type is a pay-to-pubkey, kaspa already supports others and
|
||||
may well support more in the future. This package currently provides
|
||||
implementations for the pay-to-pubkey-hash, and pay-to-script-hash address
|
||||
implementations for the pay-to-pubkey, and pay-to-script-hash address
|
||||
types.
|
||||
|
||||
To decode/encode an address:
|
||||
|
||||
addrString := "kaspa:qqfgqp8l9l90zwetj84k2jcac2m8falvvyy8xjtnhd"
|
||||
addrString := "kaspa:qqj9fg59mptxkr9j0y53j5mwurcmda5mtza9n6v9pm9uj8h0wgk6uma5pvumr"
|
||||
defaultPrefix := util.Bech32PrefixKaspa
|
||||
addr, err := util.DecodeAddress(addrString, defaultPrefix)
|
||||
if err != nil {
|
||||
|
@ -22,10 +22,10 @@ func TstAppDataDir(goos, appName string, roaming bool) string {
|
||||
return appDir(goos, appName, roaming)
|
||||
}
|
||||
|
||||
func TstAddressPubKeyHash(prefix Bech32Prefix, hash [blake2b.Size256]byte) *AddressPubKeyHash {
|
||||
return &AddressPubKeyHash{
|
||||
func TstAddressPubKey(prefix Bech32Prefix, hash [PublicKeySize]byte) *AddressPublicKey {
|
||||
return &AddressPublicKey{
|
||||
prefix: prefix,
|
||||
hash: hash,
|
||||
publicKey: hash,
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,8 +40,15 @@ func TstAddressScriptHash(prefix Bech32Prefix, hash [blake2b.Size256]byte) *Addr
|
||||
}
|
||||
|
||||
// TstAddressSAddr returns the expected script address bytes for
|
||||
// P2PKH and P2SH kaspa addresses.
|
||||
func TstAddressSAddr(addr string) []byte {
|
||||
// P2PK kaspa addresses.
|
||||
func TstAddressSAddrP2PK(addr string) []byte {
|
||||
_, decoded, _, _ := bech32.Decode(addr)
|
||||
return decoded[:PublicKeySize]
|
||||
}
|
||||
|
||||
// TstAddressSAddrP2SH returns the expected script address bytes for
|
||||
// P2SH kaspa addresses.
|
||||
func TstAddressSAddrP2SH(addr string) []byte {
|
||||
_, decoded, _, _ := bech32.Decode(addr)
|
||||
return decoded[:blake2b.Size256]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user