Skip to content

Commit

Permalink
wip on transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
QuestofIranon committed Nov 7, 2019
1 parent 94a9fae commit bf7ecc0
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 11 deletions.
3 changes: 2 additions & 1 deletion account_create_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func (transaction AccountCreateTransaction) SetKey(publicKey Ed25519PublicKey) A
protoKey := hedera_proto.Key_Ed25519{Ed25519: publicKey.keyData}

transaction.body.Key = &hedera_proto.Key{Key: &protoKey}

return transaction
}

Expand All @@ -48,7 +49,7 @@ func (transaction AccountCreateTransaction) validate() error {
return nil
}

func (transaction AccountCreateTransaction) Build() (Transaction, error) {
func (transaction AccountCreateTransaction) Build() (*Transaction, error) {
if err := transaction.validate(); err != nil {
return nil, err
}
Expand Down
7 changes: 6 additions & 1 deletion examples/create_account/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ func main() {
operatorPrivateKey,
)

newKey := hedera.NewEd25519PrivateKey()
newKey, err := hedera.GenerateEd25519PrivateKey()

if err != nil {
panic(err)
}

newPublicKey := newKey.PublicKey()

tx, err := hedera.NewAccountCreateTransaction(client).
Expand Down
116 changes: 109 additions & 7 deletions transaction.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
package hedera

import "strings"
import (
"errors"
"strings"
"time"

"github.com/hashgraph/hedera-sdk-go/hedera_proto"
)

const receiptRetryDelay = 500
const receiptInitialDelay = 1000

const prefixLen = 6

type ErrorTransactionValidation struct {
Messages []string
Expand All @@ -11,15 +22,106 @@ func (e *ErrorTransactionValidation) Error() string {
return "The following requirements were not met: \n" + strings.Join(e.Messages, "\n")
}

// fixme: this should probably be a struct with those functions implementat on it
type Transaction interface {
Execute() error
ExecuteForReceipt() (TransactionReceipt, error)
}

type TransactionBuilder interface {
SetMaxTransactionFee(uint64) *TransactionBuilder
SetMemo(string)
validate() ErrorTransactionValidation
Build() (Transaction, error)
}

type TransactionID struct {
Account AccountID
ValidStartSeconds uint64
ValidStartNanos uint32
}

func generateTransactionID(accountID AccountID) TransactionID {
now := time.Now()

return TransactionID{
accountID,
uint64(now.Unix()),
uint32(now.UnixNano() - (now.Unix() * 1e+9)),
}
}

type Transaction struct {
Kind TransactionKind
client *Client
inner hedera_proto.Transaction
}

func (transaction Transaction) AddSignature(signature []byte, publicKey Ed25519PublicKey) Transaction {
signaturePair := hedera_proto.SignaturePair{
PubKeyPrefix: publicKey.keyData,
Signature: &hedera_proto.SignaturePair_Ed25519{
Ed25519: signature,
},
}

sigmap := transaction.inner.GetSigMap()

if sigmap == nil {
sigmap = &hedera_proto.SignatureMap{}
}

sigmap.SigPair = append(sigmap.SigPair, &signaturePair)

transaction.inner.SigMap = sigmap

return transaction
}

func (transaction Transaction) Sign(privateKey Ed25519PrivateKey) Transaction {
signature := privateKey.Sign(transaction.inner.GetBodyBytes())

return transaction.AddSignature(signature, privateKey.PublicKey())
}

func (transaction Transaction) getReceipt() (*TransactionReceipt, error) {
return nil, nil
}

func (transaction Transaction) Execute() (*TransactionID, error) {
// fixme: proper error handling
if transaction.client == nil {
return nil, errors.New("No client was provided on this transaction")
}

txID := generateTransactionID(transaction.client.operator.accountID)

body := transaction.inner.GetBody()

body.TransactionID = &hedera_proto.TransactionID{
TransactionValidStart: &hedera_proto.Timestamp{
Seconds: int64(txID.ValidStartSeconds),
Nanos: int32(txID.ValidStartNanos),
},
AccountID: &hedera_proto.AccountID{
ShardNum: int64(txID.Account.Shard),
RealmNum: int64(txID.Account.Realm),
AccountNum: int64(txID.Account.Account),
},
}

// todo: use response and handle precheck codes
_, error := transaction.Kind.execute(*transaction.client, transaction.inner)

// todo: handle result errors
if error != nil {
return nil, error
}

return &txID, nil
}

func (transaction Transaction) ExecuteForReceipt() (*TransactionReceipt, error) {
_, err := transaction.Execute()

if err != nil {
return nil, err
}

// todo: add receipts
return nil, nil
}
26 changes: 26 additions & 0 deletions transaction_kind.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package hedera

import (
"context"
"errors"

"github.com/hashgraph/hedera-sdk-go/hedera_proto"
)

type TransactionKind int

const (
CryptoCreateAccount TransactionKind = iota
CryptoTransfer
)

func (tk TransactionKind) execute(client Client, tx hedera_proto.Transaction) (*hedera_proto.TransactionResponse, error) {
switch tk {
case CryptoCreateAccount:
return hedera_proto.NewCryptoServiceClient(client.conn).CreateAccount(context.TODO(), &tx)
case CryptoTransfer:
return nil, errors.New("not implemented yet")
default:
return nil, errors.New("invalid kind provided")
}
}
4 changes: 2 additions & 2 deletions transaction_receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ func TransactionReceiptFromResponse(response hedera_proto.Response) (*Transactio
return &receipt, nil
}

func (transactionReceipt TransactionReceipt) AccountID() AccountID {
func (transactionReceipt TransactionReceipt) AccountID() *AccountID {
internalID := transactionReceipt.inner.AccountID

if internalID == nil {
return nil
}

return AccountID{
return &AccountID{
uint64(internalID.ShardNum),
uint64(internalID.RealmNum),
uint64(internalID.AccountNum),
Expand Down

0 comments on commit bf7ecc0

Please sign in to comment.