Skip to content

Commit

Permalink
Merge pull request #344 from iotaledger/feat/implicit-accounts
Browse files Browse the repository at this point in the history
Implicit account creation
  • Loading branch information
cyberphysic4l authored Sep 28, 2023
2 parents 5b8b469 + e51ea10 commit 5a0850d
Show file tree
Hide file tree
Showing 18 changed files with 257 additions and 47 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ require (
github.com/iotaledger/hive.go/stringify v0.0.0-20230926122307-d671b36a4a65
github.com/iotaledger/inx-app v1.0.0-rc.3.0.20230927140518-622f63be6182
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20230927140257-bfa0bb0af2bd
github.com/iotaledger/iota.go/v4 v4.0.0-20230928093005-fe74b3839c5d
github.com/iotaledger/iota.go/v4 v4.0.0-20230928103002-093e56bf1b19
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 @@ -305,8 +305,8 @@ github.com/iotaledger/inx-app v1.0.0-rc.3.0.20230927140518-622f63be6182 h1:lQikt
github.com/iotaledger/inx-app v1.0.0-rc.3.0.20230927140518-622f63be6182/go.mod h1:q24QEsS887ZWJVX76w2kwSgC84KS7wIKOy1otuqZ2ZM=
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20230927140257-bfa0bb0af2bd h1:nFG3Zq/zFA4KhBYFX2IezX1C74zfE0DqCt0LrgTa9Ig=
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20230927140257-bfa0bb0af2bd/go.mod h1:c5778OnWpLq108YE+Eb2m8Ri/t/4ydV0TvI/Sy5YivQ=
github.com/iotaledger/iota.go/v4 v4.0.0-20230928093005-fe74b3839c5d h1:YvE8rOrBJQu9wryUAOwEEl4mu91rpocO23qKpffKdi8=
github.com/iotaledger/iota.go/v4 v4.0.0-20230928093005-fe74b3839c5d/go.mod h1:wR9xBbsofns9hFyRHFZ2bDYIb861qsfmQPVMBKcPvDo=
github.com/iotaledger/iota.go/v4 v4.0.0-20230928103002-093e56bf1b19 h1:4vN+jZJECvlfP0Bam8tonH9ndFBJoi8G0nMb4m1kpKk=
github.com/iotaledger/iota.go/v4 v4.0.0-20230928103002-093e56bf1b19/go.mod h1:wR9xBbsofns9hFyRHFZ2bDYIb861qsfmQPVMBKcPvDo=
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 @@ -141,6 +141,14 @@ func (a *AccountData) readFromReadSeeker(reader io.ReadSeeker) (int, error) {
}
bytesConsumed += bytesRead
a.BlockIssuerKeys.Add(iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519PublicKey))
case iotago.BlockIssuerKeyPublicKeyHash:
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
a.BlockIssuerKeys.Add(iotago.Ed25519PublicKeyHashBlockIssuerKeyFromImplicitAccountCreationAddress(&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
4 changes: 2 additions & 2 deletions pkg/protocol/engine/accounts/mana/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (m *Manager) GetManaOnAccount(accountID iotago.AccountID, currentSlot iotag
if err != nil {
return 0, ierrors.Errorf("failed to resolve AccountOutput for %s in slot %s: %w", accountID, currentSlot, err)
}
minDeposit := m.apiProvider.CurrentAPI().ProtocolParameters().RentStructure().MinDeposit(output.Output())
minDeposit := m.apiProvider.CurrentAPI().RentStructure().MinDeposit(output.Output())
if output.BaseTokenAmount() <= minDeposit {
mana = accounts.NewMana(output.StoredMana(), 0, output.SlotCreated())
} else {
Expand Down Expand Up @@ -92,7 +92,7 @@ func (m *Manager) ApplyDiff(slot iotago.SlotIndex, destroyedAccounts ds.Set[iota
for accountID, output := range accountOutputs {
mana, exists := m.manaVectorCache.Get(accountID)
if exists {
minDeposit := m.apiProvider.CurrentAPI().ProtocolParameters().RentStructure().MinDeposit(output.Output())
minDeposit := m.apiProvider.CurrentAPI().RentStructure().MinDeposit(output.Output())
if output.BaseTokenAmount() <= minDeposit {
mana.Update(output.StoredMana(), 0, slot)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,22 @@ func (c *CommitmentFilter) evaluateBlock(block *blocks.Block) {
switch signature := block.ProtocolBlock().Signature.(type) {
case *iotago.Ed25519Signature:
if !accountData.BlockIssuerKeys.Has(iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(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.Slot()),
})

return
// If the block issuer does not have the public key in the slot commitment, check if it is an implicit account with the corresponding address.
// There must be at least one block issuer key on any account, so extracting index 0 is fine.
// For implicit accounts there is exactly one key, so we do not have to check any other indices.
blockIssuerKey := accountData.BlockIssuerKeys[0]
// Implicit Accounts can only have Block Issuer Keys of type Ed25519PublicKeyHashBlockIssuerKey.
bikPubKeyHash, isBikPubKeyHash := blockIssuerKey.(*iotago.Ed25519PublicKeyHashBlockIssuerKey)

// Filter the block if it's not a Block Issuer Key from an Implicit Account or if the Pub Key Hashes do not match.
if !isBikPubKeyHash || bikPubKeyHash.PublicKeyHash != iotago.Ed25519PublicKeyHashBlockIssuerKeyFromPublicKey(signature.PublicKey[:]).PublicKeyHash {
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()
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,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 @@ -153,7 +154,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 @@ -162,13 +163,26 @@ func TestCommitmentFilter_NoAccount(t *testing.T) {
accounts.WithBlockIssuerKeys(iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(keyPair.PublicKey)),
),
)
keyPairImplicitAccount := ed25519.GenerateKeyPair()
implicitAddress := iotago.ImplicitAccountCreationAddressFromPubKey(keyPairImplicitAccount.PublicKey[:])
implicitAccountID := iotago.AccountID(implicitAddress[:])
tf.AddAccountData(
implicitAccountID,
accounts.NewAccountData(
implicitAccountID,
accounts.WithExpirySlot(iotago.MaxSlotIndex),
accounts.WithBlockIssuerKeys(iotago.Ed25519PublicKeyHashBlockIssuerKeyFromImplicitAccountCreationAddress(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
53 changes: 43 additions & 10 deletions pkg/protocol/engine/ledger/ledger/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,11 +382,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.MaxSlotIndex
}

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 := iotago.NewBlockIssuerKeys()
Expand Down Expand Up @@ -438,14 +446,24 @@ 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:
// If the Output is a Basic Output it can only be here if the address is an ImplicitAccountCreationAddress.
address, _ := createdOutput.Output().UnlockConditionSet().Address().Address.(*iotago.ImplicitAccountCreationAddress)
accountDiff.BlockIssuerKeysAdded = iotago.NewBlockIssuerKeys(iotago.Ed25519PublicKeyHashBlockIssuerKeyFromImplicitAccountCreationAddress(address))
accountDiff.NewExpirySlot = iotago.MaxSlotIndex
}
}
}
Expand Down Expand Up @@ -486,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 @@ -506,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 @@ -529,6 +555,13 @@ func (l *Ledger) processCreatedAndConsumedAccountOutputs(stateDiff mempool.State
accountDiff := getAccountDiff(accountDiffs, delegationOutput.ValidatorAddress.AccountID())
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
4 changes: 2 additions & 2 deletions pkg/protocol/snapshotcreator/snapshotcreator.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func createGenesisOutput(genesisTokenAmount iotago.BaseToken, genesisSeed []byte
genesisWallet := mock.NewHDWallet("genesis", genesisSeed, 0)
output := createOutput(genesisWallet.Address(), genesisTokenAmount)

if _, err := engineInstance.CurrentAPI().ProtocolParameters().RentStructure().CoversMinDeposit(output, genesisTokenAmount); err != nil {
if _, err := engineInstance.CurrentAPI().RentStructure().CoversMinDeposit(output, genesisTokenAmount); err != nil {
return ierrors.Wrap(err, "min rent not covered by Genesis output with index 0")
}

Expand All @@ -153,7 +153,7 @@ func createGenesisAccounts(accounts []AccountDetails, engineInstance *engine.Eng
for idx, genesisAccount := range accounts {
output := createAccount(genesisAccount.AccountID, genesisAccount.Address, genesisAccount.Amount, genesisAccount.Mana, genesisAccount.IssuerKey, genesisAccount.ExpirySlot, genesisAccount.StakedAmount, genesisAccount.StakingEpochEnd, genesisAccount.FixedCost)

if _, err := engineInstance.CurrentAPI().ProtocolParameters().RentStructure().CoversMinDeposit(output, genesisAccount.Amount); err != nil {
if _, err := engineInstance.CurrentAPI().RentStructure().CoversMinDeposit(output, genesisAccount.Amount); err != nil {
return ierrors.Wrapf(err, "min rent not covered by account output with index %d", idx+1)
}

Expand Down
89 changes: 87 additions & 2 deletions pkg/tests/accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func Test_TransitionAccount(t *testing.T) {
testsuite.WithAddBlockIssuerKey(newGenesisOutputKey),
testsuite.WithBlockIssuerExpirySlot(1),
)
consumedInputs, equalOutputs, equalWallets := ts.TransactionFramework.CreateBasicOutputsEqually(2, "Genesis:0")
consumedInputs, equalOutputs, equalWallets := ts.TransactionFramework.CreateBasicOutputsEqually(4, "Genesis:0")

tx1 := lo.PanicOnErr(ts.TransactionFramework.CreateTransactionWithOptions("TX1", append(accountWallets, equalWallets...),
testsuite.WithAccountInput(accountInput, true),
Expand Down Expand Up @@ -268,7 +268,7 @@ func Test_TransitionAccount(t *testing.T) {

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

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

ts.AssertAccountDiff(newAccountOutput.AccountID, block4Slot, &model.AccountDiff{
BICChange: 0,
Expand All @@ -295,6 +295,91 @@ 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.Ed25519PublicKeyHashBlockIssuerKeyFromImplicitAccountCreationAddress(implicitAccountAddress)

ts.AssertAccountData(&accounts.AccountData{
ID: implicitAccountID,
Credits: accounts.NewBlockIssuanceCredits(0, slotIndexBlock5),
ExpirySlot: iotago.MaxSlotIndex,
OutputID: implicitAccountOutputID,
BlockIssuerKeys: iotago.NewBlockIssuerKeys(implicitBlockIssuerKey),
}, ts.Nodes()...)

// TRANSITION IMPLICIT ACCOUNT TO ACCOUNT OUTPUT

fullAccountBlockIssuerKey := utils.RandBlockIssuerKey()

inputForImplicitAccountTransition, outputsForImplicitAccountTransition, fullAccountWallet := ts.TransactionFramework.TransitionImplicitAccountToAccountOutput(
"TX5:0",
testsuite.WithBlockIssuerFeature(
iotago.BlockIssuerKeys{fullAccountBlockIssuerKey},
iotago.MaxSlotIndex,
),
)

tx6 := lo.PanicOnErr(ts.TransactionFramework.CreateTransactionWithOptions("TX6", fullAccountWallet,
testsuite.WithContextInputs(iotago.TxEssenceContextInputs{
&iotago.BlockIssuanceCreditInput{
AccountID: implicitAccountID,
},
&iotago.CommitmentInput{
CommitmentID: node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID(),
},
}),
testsuite.WithInputs(inputForImplicitAccountTransition),
testsuite.WithOutputs(outputsForImplicitAccountTransition),
testsuite.WithSlotCreated(slotIndexBlock5),
))

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,
PreviousExpirySlot: iotago.MaxSlotIndex,
NewExpirySlot: iotago.MaxSlotIndex,
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, slotIndexBlock5),
ExpirySlot: iotago.MaxSlotIndex,
OutputID: fullAccountOutputID,
BlockIssuerKeys: iotago.NewBlockIssuerKeys(fullAccountBlockIssuerKey),
}, ts.Nodes()...)

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

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

0 comments on commit 5a0850d

Please sign in to comment.