Skip to content

Commit

Permalink
TRX TRC20 support
Browse files Browse the repository at this point in the history
  • Loading branch information
孙显松 committed Oct 13, 2020
1 parent d9cf253 commit b08d240
Show file tree
Hide file tree
Showing 13 changed files with 801 additions and 23 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Change log

## 2020-10-13
- 新增TRX TRC20支持

## 2020-09-02
- 新增MKF支持, 以及部分相关API
- bbc,废弃了部分API
Expand Down
136 changes: 136 additions & 0 deletions core/trx/trx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package trx

import (
"crypto/ecdsa"
"crypto/sha256"
"encoding/hex"
"strings"

"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcutil/base58"
"github.com/btcsuite/btcutil/hdkeychain"
"github.com/dabankio/wallet-core/bip44"
"github.com/dabankio/wallet-core/core"
"github.com/ethereum/go-ethereum/crypto"
trxProtoCore "github.com/fbsobreira/gotron-sdk/pkg/proto/core"
"github.com/golang/protobuf/proto"
"github.com/pkg/errors"
)

const symbol = "TRX"

// trx key derivation service
type trx struct{ core.CoinInfo }

func NewCoin(bip44Path string, seed []byte) (core.Coin, error) {
var err error
c := new(trx)
c.Symbol = symbol
c.DerivationPath, err = bip44.GetCoinDerivationPath(bip44Path, symbol)
if err != nil {
return nil, errors.Wrap(err, "bip44.GetCoinDerivationPath err:")
}
c.MasterKey, err = hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
return c, err
}

func (c *trx) DeriveAddress() (address string, err error) {
publicKeyECDSA, err := c.derivePublicKey()
if err != nil {
return
}
const addressPrefix = 0x41
return base58.CheckEncode(crypto.PubkeyToAddress(*publicKeyECDSA).Bytes(), addressPrefix), nil
}

func (c *trx) derivePublicKey() (publicKey *ecdsa.PublicKey, err error) {
privateKeyECDSA, err := c.derivePrivateKey()
if err != nil {
return
}
publicKey, ok := privateKeyECDSA.Public().(*ecdsa.PublicKey)
if !ok {
return nil, errors.New("failed to get public key")
}
return
}

func (c *trx) DerivePublicKey() (publicKey string, err error) {
publicKeyECDSA, err := c.derivePublicKey()
if err != nil {
return
}
return hex.EncodeToString(crypto.FromECDSAPub(publicKeyECDSA)), nil
}

func (c *trx) derivePrivateKey() (privateKey *ecdsa.PrivateKey, err error) {
childKey := c.MasterKey
for _, childNum := range c.DerivationPath {
childKey, err = childKey.Child(childNum)
if err != nil {
return nil, err
}
}
priKey, err := childKey.ECPrivKey()
if err != nil {
return
}
return priKey.ToECDSA(), nil
}

func (c *trx) DerivePrivateKey() (privateKey string, err error) {
priKey, err := c.derivePrivateKey()
if err != nil {
return
}
return hex.EncodeToString(crypto.FromECDSA(priKey)), nil
}

func (c *trx) DecodeTx(msg string) (tx string, err error) {
return "", errors.New("unsupported")
}

// SignWithPrivateKey .
func SignWithPrivateKey(msg, privateKey string) (string, error) {
txRawBytes, err := hex.DecodeString(msg)
if err != nil {
return "", err
}
tx := new(trxProtoCore.Transaction)
err = proto.Unmarshal(txRawBytes, tx)
if err != nil {
return "", errors.Wrap(err, "proto.Unmarshal error")
}

rawData, err := proto.Marshal(tx.GetRawData())
if err != nil {
return "", errors.Wrap(err, "proto.Marsha err")
}

privateKey = strings.TrimPrefix(privateKey, "0x")
privateKeyECDSA, err := crypto.HexToECDSA(privateKey)
if err != nil {
return "", err
}

txHash := sha256.Sum256(rawData)
signature, err := crypto.Sign(txHash[:], privateKeyECDSA)
if err != nil {
return "", err
}
tx.Signature = append(tx.Signature, signature)
txSigBytes, err := proto.Marshal(tx)
if err != nil {
return "", errors.Wrap(err, "proto.Marshal err")
}
return hex.EncodeToString(txSigBytes), nil
}

// Sign msg = trx.core.Transaction
func (c *trx) Sign(msg, privateKey string) (sig string, err error) {
return SignWithPrivateKey(msg, privateKey)
}

func (c *trx) VerifySignature(pubKey, msg, signature string) error {
return core.ErrThisFeatureIsNotSupported
}
66 changes: 66 additions & 0 deletions core/trx/trx_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package trx

import (
"fmt"
"log"
"testing"

"github.com/dabankio/wallet-core/bip44"
"github.com/dabankio/wallet-core/core"
"github.com/stretchr/testify/assert"
)

func init() {
var err error
seed, err := core.NewSeedFromMnemonic(testMnemonic, "")
coin, err = NewCoin(bip44.FullPathFormat, seed)
if err != nil {
log.Fatal(err)
}
}

var (
testMnemonic = "lecture leg select like delay limit spread retire toward west grape bachelor"
coin core.Coin
)

func TestNew(t *testing.T) {
for i := 0; i < 3; i++ {
seed, _ := core.NewSeed()
coin, _ := NewCoin(bip44.FullPathFormat, seed)
fmt.Println(coin.DerivePrivateKey())
fmt.Println(coin.DerivePublicKey())
fmt.Println(coin.DeriveAddress())
}
}

func TestTrx_DerivePrivateKey(t *testing.T) {
pkey, err := coin.DerivePrivateKey()
assert.NoError(t, err)
t.Log(pkey)
}

func TestTrx_DerivePublicKey(t *testing.T) {
pubKey, err := coin.DerivePublicKey()
assert.NoError(t, err)
t.Log(pubKey)
}

func TestTrx_DeriveAddress(t *testing.T) {
address, err := coin.DeriveAddress()
assert.NoError(t, err)
t.Log(address)
}

func TestTrx_DecodeTx(t *testing.T) {
msg := "0a85010a02a0b322083a36fcb6a57a787540c8c6f7ce9a2d5a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541748ba7f6ba19952a5d91981fa9f71d1035418c841215415faa814c0f4eb571f521530aa2e1cf80244784d718a08d06709ce5e1a59a2d12410fd4a3be763ce07420651153f977066c432509e48a2e5f6a7754e2c3784cc8084166ccdfbd21fd1b6b22e7a27d1f2ed50ffbda16eaa967fa2e0135cd6a0c2ebc001241ece66734ee6014565c4537332f0d0ba01dd5279823cc4e09fe05c8569dc40e116a49e6dfce521a72fa47ceaa24524808384f50168920ba83b55fc4c9c9f3f7b401"
coin.DecodeTx(msg)
}

func TestTrx_Sign(t *testing.T) {
bb, err := coin.Sign("0a85010a02ace62208b3f94ba5e72ef48540aefa95ce992d5a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541b917d6261d3bbe00b9183f9b375da811677f6ea31215415faa814c0f4eb571f521530aa2e1cf80244784d718a08d0670ae9dbacc992d124186effa70360c01cbeac998c88a54d9c001863b4643db3fb1faa2d5f37249c550459481e42d6132c10ef15127704f777c9fb1b73f0d332a60eacd3ef31de4799100", "27be6bc7e7a02f310528bbc2a78f724bac9240fd21e9fade9fbcf82405681b8c")
assert.NoError(t, err)
t.Log(bb)
// 0acb010a85010a02ace62208b3f94ba5e72ef48540aefa95ce992d5a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541b917d6261d3bbe00b9183f9b375da811677f6ea31215415faa814c0f4eb571f521530aa2e1cf80244784d718a08d0670ae9dbacc992d124186effa70360c01cbeac998c88a54d9c001863b4643db3fb1faa2d5f37249c550459481e42d6132c10ef15127704f777c9fb1b73f0d332a60eacd3ef31de4799100
// 0a85010a02ace62208b3f94ba5e72ef48540aefa95ce992d5a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541b917d6261d3bbe00b9183f9b375da811677f6ea31215415faa814c0f4eb571f521530aa2e1cf80244784d718a08d0670ae9dbacc992d124186effa70360c01cbeac998c88a54d9c001863b4643db3fb1faa2d5f37249c550459481e42d6132c10ef15127704f777c9fb1b73f0d332a60eacd3ef31de4799100124157954b88c61fd11d24563800463f99c6af3d447e6055f99019dee5ed365dda6b42a402a4ecd752950aedb1b6ea3d76d62176a0335009171b8a78ee04d8d3a3b500
}
13 changes: 5 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,24 @@ go 1.14

require (
github.com/aristanetworks/goarista v0.0.0-20190319235110-489128639c40 // indirect
github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c
github.com/btcsuite/btcutil v0.0.0-20190316010144-3ac1210f4b38
github.com/btcsuite/btcd v0.20.1-beta
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
github.com/cespare/cp v1.1.1 // indirect
github.com/dabankio/bbrpc v1.2.0-beta.9
github.com/dabankio/devtools4chains v0.1.1-beta.20200902
github.com/dabankio/gobbc v1.0.13
github.com/deckarep/golang-set v1.7.1 // indirect
github.com/edsrzf/mmap-go v1.0.0 // indirect
github.com/ethereum/go-ethereum v1.9.18
github.com/ethereum/go-ethereum v1.9.20
github.com/fbsobreira/gotron-sdk v0.0.0-20200910163704-5dae825f6e2e
github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a // indirect
github.com/golang/protobuf v1.4.2
github.com/gorilla/websocket v1.4.1 // indirect
github.com/mattn/go-colorable v0.1.2 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/pborman/uuid v1.2.0 // indirect
github.com/pkg/errors v0.9.1
github.com/prometheus/tsdb v0.10.0 // indirect
github.com/rjeczalik/notify v0.9.2 // indirect
github.com/rs/cors v1.6.0 // indirect
github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48 // indirect
github.com/stretchr/testify v1.6.1
github.com/tyler-smith/go-bip39 v1.0.2 // indirect
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
golang.org/x/mobile v0.0.0-20200801112145-973feb4309de // indirect
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc // indirect
Expand Down
Loading

0 comments on commit b08d240

Please sign in to comment.