Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implicit account creation #344

Merged
merged 31 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
64f5d33
add implicit account to accounts manager and check for their signatur…
cyberphysic4l Sep 15, 2023
b612ea0
fix commitment filter bug
cyberphysic4l Sep 15, 2023
1a176a5
track consumed implicit accounts
cyberphysic4l Sep 18, 2023
d564fbd
test implicit account creation
cyberphysic4l Sep 19, 2023
f64fb8b
fix commitment filter
cyberphysic4l Sep 19, 2023
03ecb8b
start accounts test additions
cyberphysic4l Sep 20, 2023
27ea6be
Fix transaction framework for implicit accounts
muXxer Sep 20, 2023
74473aa
fixes for account test
cyberphysic4l Sep 20, 2023
413298a
Merge branch 'develop' into feat/implicit-accounts
cyberphysic4l Sep 22, 2023
d976f5f
Merge branch 'develop' into feat/implicit-accounts
cyberphysic4l Sep 25, 2023
ec314bf
align with iota.go
cyberphysic4l Sep 26, 2023
dd85e27
Merge branch 'develop' into feat/implicit-accounts
cyberphysic4l Sep 26, 2023
192c415
fix merge errors
cyberphysic4l Sep 27, 2023
b15799e
use block issuer key constructor
cyberphysic4l Sep 27, 2023
2c642e8
Merge branch 'develop' into feat/implicit-accounts
cyberphysic4l Sep 27, 2023
08d48e2
update to implicit account block issuer key type to pubkeyhash in iotago
cyberphysic4l Sep 27, 2023
9f2a0d4
Document filter rules and increase resiliency
PhilippGackstatter Sep 27, 2023
c886ac1
Add comment on type assertion
PhilippGackstatter Sep 27, 2023
f7bffc7
Merge branch 'develop' into feat/implicit-accounts
cyberphysic4l Sep 27, 2023
d22c94c
go mod tidy
cyberphysic4l Sep 27, 2023
524a367
fix accounts test
cyberphysic4l Sep 27, 2023
fb6af98
remove print from accounts test
cyberphysic4l Sep 27, 2023
0242a84
go mod tidy
cyberphysic4l Sep 27, 2023
a27c9bc
state index implicit account = 0
cyberphysic4l Sep 28, 2023
7e08eb5
Merge branch 'develop' into feat/implicit-accounts
cyberphysic4l Sep 28, 2023
a94accc
go mod tidy
cyberphysic4l Sep 28, 2023
88eca77
merge errors
cyberphysic4l Sep 28, 2023
ded2b4f
Merge branch 'develop' into feat/implicit-accounts
cyberphysic4l Sep 28, 2023
51eccbc
use new account builder
cyberphysic4l Sep 28, 2023
6dab42a
Remove stray fmt printf
PhilippGackstatter Sep 28, 2023
e51ea10
Remove fmt import
PhilippGackstatter Sep 28, 2023
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ require (
github.com/iotaledger/hive.go/stringify v0.0.0-20230906114834-b50190b9f9c2
github.com/iotaledger/inx-app v1.0.0-rc.3.0.20230829161228-3f4eb50a4d14
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20230829160617-69b96c7c9f9b
github.com/iotaledger/iota.go/v4 v4.0.0-20230913143616-917572c7752d
github.com/iotaledger/iota.go/v4 v4.0.0-20230919084223-31baf7634420
github.com/labstack/echo/v4 v4.11.1
github.com/labstack/gommon v0.4.0
github.com/libp2p/go-libp2p v0.30.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,8 @@ github.com/iotaledger/inx-app v1.0.0-rc.3.0.20230829161228-3f4eb50a4d14 h1:BkDuQ
github.com/iotaledger/inx-app v1.0.0-rc.3.0.20230829161228-3f4eb50a4d14/go.mod h1:ADBXzdHXTldP0NB2Vf+KbhDxkYciGRjzQVXT6Rdne1g=
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20230829160617-69b96c7c9f9b h1:EPB/+iWeSx/WgJlzaXl8yjinxuD8CCOdi2ZPMLeeMVY=
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20230829160617-69b96c7c9f9b/go.mod h1:B7gyJP6GshCSlEmY3CxEk5TZdsMs3UNz5U92hkFDdMs=
github.com/iotaledger/iota.go/v4 v4.0.0-20230913143616-917572c7752d h1:p9IchKq6kft758XDlnN/tAEXJMXGlmQPmbdxolba1gs=
github.com/iotaledger/iota.go/v4 v4.0.0-20230913143616-917572c7752d/go.mod h1:DWCa+mXRTGWBV0EHVuvToUxAEcICe2Pab9hBlxBamKo=
github.com/iotaledger/iota.go/v4 v4.0.0-20230919084223-31baf7634420 h1:WVaB6hOwT6UhnDtM+uQlL0OBw91OdUONiaFgOvAud1g=
github.com/iotaledger/iota.go/v4 v4.0.0-20230919084223-31baf7634420/go.mod h1:DWCa+mXRTGWBV0EHVuvToUxAEcICe2Pab9hBlxBamKo=
github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY=
github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM=
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
Expand Down
8 changes: 8 additions & 0 deletions pkg/protocol/engine/accounts/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@ func (a *AccountData) readFromReadSeeker(reader io.ReadSeeker) (int, error) {
}
bytesConsumed += bytesRead
blockIssuerKeys[i] = iotago.BlockIssuerKeyEd25519FromPublicKey(ed25519PublicKey)
case iotago.Ed25519BlockIssuerKeyAddress:
var implicitAccountCreationAddress iotago.ImplicitAccountCreationAddress
bytesRead, err = io.ReadFull(reader, implicitAccountCreationAddress[:])
if err != nil {
return bytesConsumed, ierrors.Wrapf(err, "unable to read address %d for accountID %s", i, a.ID)
}
bytesConsumed += bytesRead
blockIssuerKeys[i] = iotago.BlockIssuerKeyEd25519AddressFromAddress(&implicitAccountCreationAddress)
default:
return bytesConsumed, ierrors.Wrapf(err, "unsupported block issuer key type %d for accountID %s at offset %d", blockIssuerKeyType, a.ID, i)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,23 @@ func (c *CommitmentFilter) evaluateBlock(block *blocks.Block) {
switch signature := block.ProtocolBlock().Signature.(type) {
case *iotago.Ed25519Signature:
if !accountData.BlockIssuerKeys.Has(iotago.BlockIssuerKeyEd25519FromPublicKey(signature.PublicKey)) {
c.events.BlockFiltered.Trigger(&commitmentfilter.BlockFilteredEvent{
Block: block,
Reason: ierrors.Wrapf(ErrInvalidSignature, "block issuer account %s does not have public key %s in slot %d", block.ProtocolBlock().IssuerID, signature.PublicKey, block.ProtocolBlock().SlotCommitmentID.Index()),
// if the block issuer does not have the public key in the slot commitment, check if it has an implicit account with the corresponding address
var hasAddress = false
accountData.BlockIssuerKeys.Range(func(element iotago.BlockIssuerKey) {
cyberphysic4l marked this conversation as resolved.
Show resolved Hide resolved
if keyAddress, isAddress := element.(iotago.BlockIssuerKeyEd25519Address); isAddress {
if keyAddress.Address.Equal(iotago.ImplicitAccountCreationAddressFromPubKey(signature.PublicKey[:])) {
hasAddress = true
}
}
})

return
if !hasAddress {
c.events.BlockFiltered.Trigger(&commitmentfilter.BlockFilteredEvent{
Block: block,
Reason: ierrors.Wrapf(ErrInvalidSignature, "block issuer account %s does not have block issuer key corresponding to public key %s in slot %d", block.ProtocolBlock().IssuerID, signature.PublicKey, block.ProtocolBlock().SlotCommitmentID.Index()),
})

return
}
}
signingMessage, err := block.ProtocolBlock().SigningMessage(blockAPI)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ func TestCommitmentFilter_NoAccount(t *testing.T) {

tf.CommitmentFilter.events.BlockFiltered.Hook(func(event *commitmentfilter.BlockFilteredEvent) {
require.NotEqual(t, "withAccount", event.Block.ID().Alias())
require.NotEqual(t, "withImplicitAccount", event.Block.ID().Alias())
})

keyPair := ed25519.GenerateKeyPair()
Expand All @@ -165,7 +166,7 @@ func TestCommitmentFilter_NoAccount(t *testing.T) {
addr := iotago.Ed25519AddressFromPubKey(keyPair.PublicKey[:])
accountID := iotago.AccountID(addr[:])

// register the account in the proxy account manager
// register the accounts in the proxy account manager
tf.AddAccountData(
accountID,
accounts.NewAccountData(
Expand All @@ -174,13 +175,26 @@ func TestCommitmentFilter_NoAccount(t *testing.T) {
accounts.WithBlockIssuerKeys(iotago.BlockIssuerKeyEd25519FromPublicKey(keyPair.PublicKey)),
),
)
keyPairImplicitAccount := ed25519.GenerateKeyPair()
implicitAddress := iotago.ImplicitAccountCreationAddressFromPubKey(keyPairImplicitAccount.PublicKey[:])
implicitAccountID := iotago.AccountID(implicitAddress[:])
tf.AddAccountData(
implicitAccountID,
accounts.NewAccountData(
implicitAccountID,
accounts.WithExpirySlot(math.MaxUint64),
accounts.WithBlockIssuerKeys(iotago.BlockIssuerKeyEd25519AddressFromAddress(implicitAddress)),
),
)

tf.AddRMCData(currentSlot-currentAPI.ProtocolParameters().MaxCommittableAge(), iotago.Mana(0))

tf.IssueSignedBlockAtSlot("withAccount", currentSlot, commitmentID, keyPair)

otherKeyPair := ed25519.GenerateKeyPair()
tf.IssueSignedBlockAtSlot("noAccount", currentSlot, commitmentID, otherKeyPair)
keyPairNoAccount := ed25519.GenerateKeyPair()
tf.IssueSignedBlockAtSlot("noAccount", currentSlot, commitmentID, keyPairNoAccount)

tf.IssueSignedBlockAtSlot("withImplicitAccount", currentSlot, commitmentID, keyPairImplicitAccount)
}

func TestCommitmentFilter_BurnedMana(t *testing.T) {
Expand Down
54 changes: 44 additions & 10 deletions pkg/protocol/engine/ledger/ledger/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ledger

import (
"io"
"math"

"github.com/iotaledger/hive.go/core/safemath"
"github.com/iotaledger/hive.go/ds"
Expand Down Expand Up @@ -388,11 +389,19 @@ func (l *Ledger) prepareAccountDiffs(accountDiffs map[iotago.AccountID]*model.Ac
// case 1.
continue
}
accountDiff.NewOutputID = createdOutput.OutputID()
accountDiff.PreviousOutputID = consumedOutput.OutputID()

// case 2.
// created output can never be an implicit account as these can not be transitioned, but consumed output can be.
switch consumedOutput.Output().Type() {
case iotago.OutputAccount:
accountDiff.PreviousExpirySlot = consumedOutput.Output().FeatureSet().BlockIssuer().ExpirySlot
case iotago.OutputBasic:
accountDiff.PreviousExpirySlot = iotago.SlotIndex(math.MaxUint64)
}

accountDiff.PreviousOutputID = consumedOutput.OutputID()
accountDiff.NewOutputID = createdOutput.OutputID()
accountDiff.NewExpirySlot = createdOutput.Output().FeatureSet().BlockIssuer().ExpirySlot
accountDiff.PreviousExpirySlot = consumedOutput.Output().FeatureSet().BlockIssuer().ExpirySlot

oldPubKeysSet := accountData.BlockIssuerKeys
newPubKeysSet := ds.NewSet[iotago.BlockIssuerKey]()
Expand Down Expand Up @@ -437,15 +446,25 @@ func (l *Ledger) prepareAccountDiffs(accountDiffs map[iotago.AccountID]*model.Ac
// have some values from the allotment, so no need to set them explicitly.
accountDiff.NewOutputID = createdOutput.OutputID()
accountDiff.PreviousOutputID = iotago.EmptyOutputID
accountDiff.NewExpirySlot = createdOutput.Output().FeatureSet().BlockIssuer().ExpirySlot
accountDiff.PreviousExpirySlot = 0
accountDiff.BlockIssuerKeysAdded = createdOutput.Output().FeatureSet().BlockIssuer().BlockIssuerKeys

if stakingFeature := createdOutput.Output().FeatureSet().Staking(); stakingFeature != nil {
accountDiff.ValidatorStakeChange = int64(stakingFeature.StakedAmount)
accountDiff.StakeEndEpochChange = int64(stakingFeature.EndEpoch)
accountDiff.FixedCostChange = int64(stakingFeature.FixedCost)
switch createdOutput.Output().Type() {
// for account outputs, get block issuer keys from the block issuer feature, and check for staking info.
case iotago.OutputAccount:
accountDiff.BlockIssuerKeysAdded = createdOutput.Output().FeatureSet().BlockIssuer().BlockIssuerKeys
accountDiff.NewExpirySlot = createdOutput.Output().FeatureSet().BlockIssuer().ExpirySlot
if stakingFeature := createdOutput.Output().FeatureSet().Staking(); stakingFeature != nil {
accountDiff.ValidatorStakeChange = int64(stakingFeature.StakedAmount)
accountDiff.StakeEndEpochChange = int64(stakingFeature.EndEpoch)
accountDiff.FixedCostChange = int64(stakingFeature.FixedCost)
}
// for basic outputs (implicit accounts), get block issuer keys from the address in the unlock conditions.
case iotago.OutputBasic:
address, _ := createdOutput.Output().UnlockConditionSet().Address().Address.(*iotago.ImplicitAccountCreationAddress)
PhilippGackstatter marked this conversation as resolved.
Show resolved Hide resolved
accountDiff.BlockIssuerKeysAdded = iotago.BlockIssuerKeys{iotago.BlockIssuerKeyEd25519AddressFromAddress(address)}
accountDiff.NewExpirySlot = iotago.SlotIndex(math.MaxUint64)
}

}
}

Expand Down Expand Up @@ -485,6 +504,14 @@ func (l *Ledger) processCreatedAndConsumedAccountOutputs(stateDiff mempool.State
// the delegation output was created => determine later if we need to add the stake to the validator
delegation, _ := createdOutput.Output().(*iotago.DelegationOutput)
createdAccountDelegation[delegation.DelegationID] = delegation

case iotago.OutputBasic:
// if a basic output is sent to an implicit account creation address, we need to create the account
if createdOutput.Output().UnlockConditionSet().Address().Address.Type() == iotago.AddressImplicitAccountCreation {
accountID := iotago.AccountIDFromOutputID(outputID)
l.events.AccountCreated.Trigger(accountID)
createdAccounts[accountID] = createdOutput
}
}

return true
Expand All @@ -505,7 +532,7 @@ func (l *Ledger) processCreatedAndConsumedAccountOutputs(stateDiff mempool.State
switch spentOutput.OutputType() {
case iotago.OutputAccount:
consumedAccount, _ := spentOutput.Output().(*iotago.AccountOutput)
// if we transition / destroy an account that doesn't have a block issuer feature or staking, we don't need to track the changes.
// if we transition / destroy an account output that doesn't have a block issuer feature or staking, we don't need to track the changes.
if consumedAccount.FeatureSet().BlockIssuer() == nil && consumedAccount.FeatureSet().Staking() == nil {
return true
}
Expand All @@ -528,6 +555,13 @@ func (l *Ledger) processCreatedAndConsumedAccountOutputs(stateDiff mempool.State
accountDiff := getAccountDiff(accountDiffs, delegationOutput.ValidatorID)
accountDiff.DelegationStakeChange -= int64(delegationOutput.DelegatedAmount)
}

case iotago.OutputBasic:
// if a basic output (implicit account) is consumed, get the accountID as hash of the output ID.
if spentOutput.Output().UnlockConditionSet().Address().Address.Type() == iotago.AddressImplicitAccountCreation {
accountID := iotago.AccountIDFromOutputID(outputID)
consumedAccounts[accountID] = spentOutput
}
}

return true
Expand Down
77 changes: 76 additions & 1 deletion pkg/tests/accounts_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tests

import (
"math"
"testing"

"github.com/iotaledger/hive.go/ds"
Expand Down Expand Up @@ -276,7 +277,7 @@ func Test_TransitionAccount(t *testing.T) {

block4 := ts.IssueBlockAtSlotWithOptions("block4", slotIndexBlock4, node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment(), node1, tx4, blockfactory.WithStrongParents(latestParent.ID()))

_ = ts.CommitUntilSlot(slotIndexBlock4, activeNodes, block4)
latestParent = ts.CommitUntilSlot(slotIndexBlock4, activeNodes, block4)

ts.AssertAccountDiff(newAccountOutput.AccountID, slotIndexBlock4, &model.AccountDiff{
BICChange: 0,
Expand All @@ -303,6 +304,80 @@ func Test_TransitionAccount(t *testing.T) {
ValidatorStake: 10000,
}, ts.Nodes()...)

// CREATE IMPLICIT ACCOUNT FROM BASIC UTXO
inputForImplicitAccount, outputsForImplicitAccount, implicitAccountAddress, implicitWallet := ts.TransactionFramework.CreateImplicitAccountFromInput("TX1:3")

tx5 := lo.PanicOnErr(ts.TransactionFramework.CreateTransactionWithOptions("TX5", implicitWallet,
testsuite.WithInputs(inputForImplicitAccount),
testsuite.WithOutputs(outputsForImplicitAccount),
))

implicitAccountOutput := ts.TransactionFramework.Output("TX5:0")
implicitAccountOutputID := implicitAccountOutput.OutputID()
implicitAccountID := iotago.AccountIDFromOutputID(implicitAccountOutputID)

slotIndexBlock5 := latestParent.ID().Index()

block5 := ts.IssueBlockAtSlotWithOptions("block5", slotIndexBlock5, node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment(), node1, tx5, blockfactory.WithStrongParents(latestParent.ID()))

latestParent = ts.CommitUntilSlot(slotIndexBlock5, activeNodes, block5)

var implicitBlockIssuerKey iotago.BlockIssuerKey = iotago.BlockIssuerKeyEd25519AddressFromAddress(implicitAccountAddress)

ts.AssertAccountData(&accounts.AccountData{
ID: implicitAccountID,
Credits: accounts.NewBlockIssuanceCredits(0, slotIndexBlock5),
ExpirySlot: iotago.SlotIndex(math.MaxUint64),
OutputID: implicitAccountOutputID,
BlockIssuerKeys: ds.NewSet(implicitBlockIssuerKey),
}, ts.Nodes()...)

// TRANSITION IMPLICIT ACCOUNT TO ACCOUNT OUTPUT

fullAccountBlockIssuerKey := utils.RandBlockIssuerKey()

inputForImplicitAccountTransition, outputsForImplicitAccountTransition, fullAccountWallet := ts.TransactionFramework.TransitionImplicitAccountToAccountOutput(
"TX5:0",
testsuite.WithBlockIssuerFeature(&iotago.BlockIssuerFeature{
BlockIssuerKeys: iotago.BlockIssuerKeys{fullAccountBlockIssuerKey},
ExpirySlot: math.MaxUint64,
}),
)

tx6 := lo.PanicOnErr(ts.TransactionFramework.CreateTransactionWithOptions("TX6", fullAccountWallet,
testsuite.WithInputs(inputForImplicitAccountTransition),
testsuite.WithOutputs(outputsForImplicitAccountTransition),
))

slotIndexBlock6 := latestParent.ID().Index()

block6 := ts.IssueBlockAtSlotWithOptions("block6", slotIndexBlock6, node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment(), node1, tx6, blockfactory.WithStrongParents(latestParent.ID()))

latestParent = ts.CommitUntilSlot(slotIndexBlock6, activeNodes, block6)

fullAccountOutputID := ts.TransactionFramework.Output("TX6:0").OutputID()

ts.AssertAccountDiff(implicitAccountID, slotIndexBlock6, &model.AccountDiff{
BICChange: 0,
PreviousUpdatedTime: 0,
NewOutputID: fullAccountOutputID,
PreviousOutputID: implicitAccountOutputID,
BlockIssuerKeysAdded: iotago.BlockIssuerKeys{fullAccountBlockIssuerKey},
BlockIssuerKeysRemoved: iotago.BlockIssuerKeys{implicitBlockIssuerKey},
ValidatorStakeChange: 0,
StakeEndEpochChange: 0,
FixedCostChange: 0,
DelegationStakeChange: 0,
}, false, ts.Nodes()...)

ts.AssertAccountData(&accounts.AccountData{
ID: implicitAccountID,
Credits: accounts.NewBlockIssuanceCredits(0, slotIndexBlock6),
ExpirySlot: iotago.SlotIndex(math.MaxUint64),
OutputID: implicitAccountOutputID,
BlockIssuerKeys: ds.NewSet(fullAccountBlockIssuerKey),
}, ts.Nodes()...)

ts.Wait(ts.Nodes()...)
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/testsuite/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (t *TestSuite) AssertAccountData(accountData *accounts.AccountData, nodes .
}

if !cmp.Equal(accountData.BlockIssuerKeys.ToSlice(), actualAccountData.BlockIssuerKeys.ToSlice()) {
return ierrors.Errorf("AssertAccountData: %s: accountID %s expected pub keys %s, got %s", node.Name, accountData.ID, accountData.BlockIssuerKeys, actualAccountData.BlockIssuerKeys)
return ierrors.Errorf("AssertAccountData: %s: accountID %s expected pub keys %s, got %s", node.Name, accountData.ID, accountData.BlockIssuerKeys.ToSlice(), actualAccountData.BlockIssuerKeys.ToSlice())
}

if accountData.StakeEndEpoch != actualAccountData.StakeEndEpoch {
Expand Down
18 changes: 15 additions & 3 deletions pkg/testsuite/mock/hdwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/wollac/iota-crypto-demo/pkg/slip10"
"github.com/wollac/iota-crypto-demo/pkg/slip10/eddsa"

"github.com/iotaledger/hive.go/ierrors"
"github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger"
iotago "github.com/iotaledger/iota.go/v4"
)
Expand Down Expand Up @@ -101,11 +102,22 @@ func (hd *HDWallet) Outputs() []*utxoledger.Output {
}

// Address calculates an ed25519 address by using slip10.
func (hd *HDWallet) Address() *iotago.Ed25519Address {
func (hd *HDWallet) Address(addressType ...iotago.AddressType) iotago.DirectUnlockableAddress {
_, pubKey := hd.KeyPair()
addr := iotago.Ed25519AddressFromPubKey(pubKey)

return addr
addrType := iotago.AddressEd25519
if len(addressType) > 0 {
addrType = addressType[0]
}

switch addrType {
case iotago.AddressEd25519:
return iotago.Ed25519AddressFromPubKey(pubKey)
case iotago.AddressImplicitAccountCreation:
return iotago.ImplicitAccountCreationAddressFromPubKey(pubKey)
default:
panic(ierrors.Wrapf(iotago.ErrUnknownAddrType, "type %d", addressType))
}
}

func (hd *HDWallet) PrintStatus() {
Expand Down
Loading