Skip to content
Merged
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
1,058 changes: 1,058 additions & 0 deletions api/cosmos/crypto/segwit/keys.pulsar.go

Large diffs are not rendered by default.

1,059 changes: 1,059 additions & 0 deletions api/cosmos/crypto/taproot/keys.pulsar.go

Large diffs are not rendered by default.

20 changes: 15 additions & 5 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ import (
solomachine "github.com/cosmos/ibc-go/v8/modules/light-clients/06-solomachine"
ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint"
"github.com/prometheus/client_golang/prometheus"
"github.com/sideprotocol/side/bitcoin"
"github.com/spf13/cast"

"github.com/CosmWasm/wasmd/x/wasm"
Expand All @@ -136,7 +137,10 @@ import (
lendingkeeper "github.com/sideprotocol/side/x/lending/keeper"
lendingmodule "github.com/sideprotocol/side/x/lending/module"
lendingtypes "github.com/sideprotocol/side/x/lending/types"

// this line is used by starport scaffolding # stargate/app/moduleImport

btccodec "github.com/sideprotocol/side/crypto/codec"
)

const (
Expand Down Expand Up @@ -310,7 +314,7 @@ func New(
SigningOptions: signing.Options{
AddressCodec: btcbridgecodec.NewBech32Codec(
sdk.GetConfig().GetBech32AccountAddrPrefix(),
sdk.GetConfig().GetBtcChainCfg().Bech32HRPSegwit,
bitcoin.Network.Bech32HRPSegwit,
),
ValidatorAddressCodec: address.Bech32Codec{
Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(),
Expand All @@ -320,8 +324,14 @@ func New(
if err != nil {
panic(err)
}
appCodec := codec.NewProtoCodec(interfaceRegistry)

legacyAmino := codec.NewLegacyAmino()

btccodec.RegisterCrypto(legacyAmino)
btccodec.RegisterInterfaces(interfaceRegistry)

appCodec := codec.NewProtoCodec(interfaceRegistry)

txConfig := authtx.NewTxConfig(appCodec, authtx.DefaultSignModes)

std.RegisterLegacyAminoCodec(legacyAmino)
Expand Down Expand Up @@ -409,7 +419,7 @@ func New(
maccPerms,
btcbridgecodec.NewBech32Codec(
sdk.GetConfig().GetBech32AccountAddrPrefix(),
sdk.GetConfig().GetBtcChainCfg().Bech32HRPSegwit,
bitcoin.Network.Bech32HRPSegwit,
),
sdk.GetConfig().GetBech32AccountAddrPrefix(),
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
Expand Down Expand Up @@ -928,7 +938,7 @@ func New(
BankKeeper: app.BankKeeper,
SignModeHandler: txConfig.SignModeHandler(),
FeegrantKeeper: app.FeeGrantKeeper,
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
SigGasConsumer: bitcoin.DefaultSigVerificationGasConsumer,
},
)
if err != nil {
Expand Down Expand Up @@ -1039,7 +1049,7 @@ func (app *App) AutoCliOpts() autocli.AppOptions {
ModuleOptions: runtimeservices.ExtractAutoCLIOptions(app.ModuleManager.Modules),
AddressCodec: btcbridgecodec.NewBech32Codec(
sdk.GetConfig().GetBech32AccountAddrPrefix(),
sdk.GetConfig().GetBtcChainCfg().Bech32HRPSegwit,
bitcoin.Network.Bech32HRPSegwit,
),
ValidatorAddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()),
ConsensusAddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()),
Expand Down
4 changes: 1 addition & 3 deletions app/config.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package app

import (
"github.com/btcsuite/btcd/chaincfg"

sdk "github.com/cosmos/cosmos-sdk/types"
)

Expand All @@ -19,6 +17,6 @@ func init() {
config.SetBech32PrefixForAccount(AccountAddressPrefix, accountPubKeyPrefix)
config.SetBech32PrefixForValidator(validatorAddressPrefix, validatorPubKeyPrefix)
config.SetBech32PrefixForConsensusNode(consNodeAddressPrefix, consNodePubKeyPrefix)
config.SetBtcChainCfg(&chaincfg.SigNetParams)
// config.SetBtcChainCfg(&chaincfg.TestNet3Params)
config.Seal()
}
123 changes: 123 additions & 0 deletions bitcoin/address_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package bitcoin_test

import (
"strings"
"testing"

"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/btcutil/bech32"
"github.com/btcsuite/btcd/chaincfg"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/sideprotocol/side/crypto/keys/segwit"
"github.com/sideprotocol/side/crypto/keys/taproot"
"github.com/stretchr/testify/assert"
)

func TestAddressEncodeDecode(t *testing.T) {

conf := sdk.GetConfig()
conf.SetBech32PrefixForAccount("side", "side")
conf.Seal()

adds := []string{
"side10d07y265gmmuvt4z0w9aw880jnsr700jwrwlg5",
"bc1qqs4cyfvr6fwlca38hvyrgwl08k7cxme6jw3rr6",
"bc1q73ssvy27zd8kjhrzjalzjkfdya0kd9na8pz00n",
"bc1q3v4fcnzdtduepkxhuq4cwehsw3pgtn4gakpc9t",
"bc1pln2mzgrk689xfuacgmwpym95karxf8283qh9k7ze5ucc7crl6qrq4w30es",
"bc1p93svdel208e2wva9gmnqsm3hd5p0k768a9pyg0ptd7r4lzl0sxvqeaw5gv",
}

for _, a := range adds {

addr, err := sdk.AccAddressFromBech32(a)
assert.NoError(t, err, "invalid address "+a)
if strings.HasPrefix(a, "side") {
assert.Equal(t, 20, len(addr.Bytes()), a)
} else if strings.HasPrefix(a, "bc1q") {
assert.Equal(t, 33, len(addr.Bytes()), a)
} else {
assert.Equal(t, 53, len(addr.Bytes()), a)
}

text_addr := addr.String()
assert.EqualValues(t, a, text_addr, "address should equals")

}

}

func TestGenKeys(t *testing.T) {

conf := sdk.GetConfig()
conf.SetBech32PrefixForAccount("side", "side")
conf.Seal()

// hash := btcutil.Hash160([]byte{0, 3, 3, 3, 3, 3})
hash := make([]byte, 32, 32)
assert.Equal(t, 32, len(hash))

// sh, err := btcutil.NewAddressScriptHashFromHash(hash, &chaincfg.MainNetParams)
// assert.NoError(t, err)
std, err := btcutil.NewAddressTaproot(hash, &chaincfg.MainNetParams)
assert.NoError(t, err)
assert.Equal(t, 32, len(std.AddressSegWit.ScriptAddress()))
// println(std.ScriptAddress())
text := std.AddressSegWit.EncodeAddress()
_, bte, err := bech32.Decode(text)
assert.NoError(t, err)
assert.Equal(t, 53, len(bte), text)
a_str := sdk.MustAccAddressFromBech32(text)
assert.Equal(t, 53, len(a_str.Bytes()), text)
assert.Equal(t, bte, a_str.Bytes())

addrs := []sdk.Address{sdk.AccAddress(taproot.GenPrivKey().PubKey().Address()), sdk.AccAddress(segwit.GenPrivKey().PubKey().Address())}

for _, a := range addrs {
assert.Equal(t, true, strings.HasPrefix(a.String(), "bc"), a.String())
if strings.HasPrefix(a.String(), "bc1p") {
assert.Equal(t, 53, len(a.Bytes()), a.String())
a2, err := sdk.AccAddressFromBech32(a.String())
assert.NoError(t, err)
assert.Equal(t, 53, len(a2.Bytes()))
} else {
assert.Equal(t, 33, len(a.Bytes()), a.String())
}
// a2, err := sdk.AccAddressFromBech32(a.String())
// assert.Equal(t, 53, len(a2.Bytes()))
// assert.NoError(t, err, a.String())
// assert.Equal(t, a.Bytes(), a2.Bytes(), a.String())
}
}

func TestValAddressEncodeDecode(t *testing.T) {

conf := sdk.GetConfig()
conf.SetBech32PrefixForAccount("side", "side")
conf.SetBech32PrefixForValidator("sidevaloper", "sidevaloper")
conf.Seal()

vals := []string{
// "sidevaloper1qqwpwrc0qs0pvrc6rvrsxrc2p583vqstpgdqxxsmzgp3y9gfpvqp7srxm9c", // error case
// "sidevaloper1qqgsc9gfrqfsyrgtp5wpjqgkqct3cqq4rq8pj9cspcgszzqtzv2ssmdxyv7",
"sidevaloper1pfakusycd3aful428aqm6ljclu36vk6rzxqvu72g9e7jzaukswgnqd7xhsc",
"sidevaloper1p8990duvf0d23jelthdl2qgwfrrylny5zul0awymk7j45cjtm52eqqq7yxc",
"sidevaloper1qfwqngtkrmlytqkqsd54k9t4htufp0hw9sndewh",
}

for _, a := range vals {

addr, err := sdk.ValAddressFromBech32(a)
assert.NoError(t, err, "invalid address "+a)
if strings.HasPrefix(a, "sidevaloper1p") {
assert.Equal(t, 53, len(addr))
} else {
assert.Equal(t, 33, len(addr))
}

text_addr := addr.String()
assert.EqualValues(t, a, text_addr, "address should equals")

}

}
102 changes: 102 additions & 0 deletions bitcoin/algo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package bitcoin

import (
"strings"

"github.com/cosmos/go-bip39"

"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/sideprotocol/side/crypto/keys/segwit"
"github.com/sideprotocol/side/crypto/keys/taproot"
)

const (
SegWitType = hd.PubKeyType("segwit")
TaprootType = hd.PubKeyType("taproot")
)

var SegWit = segWigAlgo{}
var Taproot = taprootAlgo{}

type segWigAlgo struct{}

func (s segWigAlgo) Name() hd.PubKeyType {
return SegWitType
}

// Derive derives and returns the secp256k1 private key for the given seed and HD path.
func (s segWigAlgo) Derive() hd.DeriveFn {
return func(mnemonic string, bip39Passphrase, hdPath string) ([]byte, error) {
if !strings.HasPrefix(hdPath, "m/84'") {
sps := strings.Split(hdPath, "/")
sps[1] = "84'" // replace purpose
sps[2] = "0'"
hdPath = strings.Join(sps, "/")
}
println("hdPath", hdPath)
seed, err := bip39.NewSeedWithErrorChecking(mnemonic, bip39Passphrase)
if err != nil {
return nil, err
}

masterPriv, ch := hd.ComputeMastersFromSeed(seed)
if len(hdPath) == 0 {
return masterPriv[:], nil
}
derivedKey, err := hd.DerivePrivateKeyForPath(masterPriv, ch, hdPath)

return derivedKey, err
}
}

// Generate generates a secp256k1 private key from the given bytes.
func (s segWigAlgo) Generate() hd.GenerateFn {
return func(bz []byte) types.PrivKey {
bzArr := make([]byte, segwit.PrivKeySize)
copy(bzArr, bz)

return &segwit.PrivKey{Key: bzArr}
}
}

type taprootAlgo struct{}

func (s taprootAlgo) Name() hd.PubKeyType {
return TaprootType
}

// Derive derives and returns the secp256k1 private key for the given seed and HD path.
func (s taprootAlgo) Derive() hd.DeriveFn {
return func(mnemonic string, bip39Passphrase, hdPath string) ([]byte, error) {
if !strings.HasPrefix(hdPath, "m/86'") {
sps := strings.Split(hdPath, "/")
sps[1] = "86'" // replace purpose
sps[2] = "0'"
hdPath = strings.Join(sps, "/")
// panic("Invalid HD path for Taproot")
}
seed, err := bip39.NewSeedWithErrorChecking(mnemonic, bip39Passphrase)
if err != nil {
return nil, err
}

masterPriv, ch := hd.ComputeMastersFromSeed(seed)
if len(hdPath) == 0 {
return masterPriv[:], nil
}
derivedKey, err := hd.DerivePrivateKeyForPath(masterPriv, ch, hdPath)

return derivedKey, err
}
}

// Generate generates a secp256k1 private key from the given bytes.
func (s taprootAlgo) Generate() hd.GenerateFn {
return func(bz []byte) types.PrivKey {
bzArr := make([]byte, taproot.PrivKeySize)
copy(bzArr, bz)

return &taproot.PrivKey{Key: bzArr}
}
}
Loading