Skip to content

Commit

Permalink
docs(adr): ADR-007: Address generation of chain link proof (#727)
Browse files Browse the repository at this point in the history
## Description

References: #724



---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://docs.cosmos.network/v0.44/building-modules/intro.html)
- [ ] included the necessary unit and integration [tests](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
  • Loading branch information
dadamu authored Sep 1, 2022
1 parent 94bd0d0 commit d968175
Showing 1 changed file with 162 additions and 0 deletions.
162 changes: 162 additions & 0 deletions docs/architecture/adr-007-address-generation-of-chain-link-proof.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# ADR 007: Address generation of chain link proof

## Changelog

- January 20th, 2022: Initial draft;
- July 28th, 2022: First review;

## Status

PROPOSED

## Abstract

Currently, Desmos allows linking other chains accounts which addresses are formatted using either the `Bech32`, `Base58` or `Hex` encoding and generated using a single algorithm specific to the encoding itself. Since Desmos idea is to support as many chains as possible, we SHOULD split the address generation algorithm from the encoding algorithm so that more chains can be linked properly.

## Context

The `x/profiles` module gives users the possibility to link their profile to different external accounts. However, each one of the supported address formats currently supports only one generation algorithm.

`Bech32Address` relies on the address generation algorithm specific of Cosmos-SDK chains:
- for single signature accounts:
```
ripemd160(sha256(32 bytes public key))[:20]
```
- for multi-sig accounts:
```
sha256(aminoCdc.Marshal(multisig public key))[:20]
```

`Base58Address` relies on the Solana algorithm:
```
(32 bytes public key)[:32]
```

`HexAddress` relies on the Ethereum algorithm:
```
keccak64(64 bytes public key)[12:]
```

Due to the fact all the `AddressData` implementations are highly coupled to a single address generation function, it is currently impossible to link an address that needs to be encoded using a supported encoding method but is generated using a different algorithm. This is the case of Elrond addresses which are encoded using the `Bech32` encoding algorithm, but are generated using an algorithm that is different from the Cosmos one.

## Decision

In order to allow developers to integrate any kind of address, we will review how the current `Address` structure is made. Instead of using an interface with multiple implementations based on the encoding algorithm, we will use a single structure that allows to specify both the encoding algorithm and the hashing algorithm(s) that should be used to get the proper address:

```protobuf
syntax = "proto3";
// Address contains the data of an external address
message Address {
// Encoded value of the address
string value = 1;
// Algorithm that has been used in order to generate the address starting from the public key bytes
GenerationAlgorithm generation_algorithm = 2;
// Algorithm that needs to be used to properly encode the address
google.proto.Any encoding_algorithm = 3 [ (cosmos_proto.accepts_interface) = "AddressEncoding" ];
}
// GenerationAlgorithm represents various address generation algorithms
enum GenerationAlgorithm {
// GENERATION_ALGORITHM_UNKNOWN represents an unknown algorithm and will be discarded
GENERATION_ALGORITHM_UNKNOWN = 0;
// GENERATION_ALGORITHM_COSMOS represents the Cosmos generation algorithm
GENERATION_ALGORITHM_COSMOS = 1;
// GENERATION_ALGORITHM_EVM represents the EVM generation algorithm
GENERATION_ALGORITHM_EVM = 2;
// GENERATION_ALGORITHM_DO_NOTHING should be used when the public key bytes do not need to be modified
GENERATION_ALGORITHM_DO_NOTHING = 3;
}
// Bech32Encoding represents the encoding algorithm based on the Bech32 format
message Bech32Encoding {
option (cosmos_proto.implements_interface) = "AddressEncoding";
// Prefix to be used
string prefix = 1;
}
// Base58Encoding represents the encoding algorithm based on the Base58 format
message Base58Encoding {
option (cosmos_proto.implements_interface) = "AddressEncoding";
// (optional) Prefix to be used
string prefix = 1;
}
// HexEncoding represents the encoding algorithm based on the Hex format
message HexEncoding {
option (cosmos_proto.implements_interface) = "AddressEncoding";
// (optional) Prefix to be used
string prefix = 1;
// (optional) Whether the address should be upper case or not (default: false)
bool uppercase = 2;
}
```

We will also define the following methods for the `Address` structure:

```go
// Validate validates the given public key against this address, to make sure they match
func (a *Address) Validate(pubKey cryptotypes.PubKey) error {
addressBytes, err := hex.DecodeString(a.Value)
if err != nil {
return err
}

// Generate the address bytes from the pub key
generatedBytes, err := generateAddressBytes(pubKey, a.GenerationAlgorithm)
if err != nil {
return err
}

// Compare the bytes
if !bytes.Equals(addressBytes, generatedBytes) {
return fmt.Errrorf("address bytes do not match generated ones: expected %s but got %s", addressBytes, generatedBytes)
}

return nil
}

// generateAddressBytes generates the address bytes starting from the given public key
// and using the provided generation algorithm
func generateAddressBytes(pubKey cryptotypes.PubKey, generationAlgorithm GenerationAlgorithm) ([]byte, error) {
// ...
}

// GetValue returns the string value of the address, encoded as it should be
func (a *Address) GetValue() string {
return a.Encoding.GetCachedValue().(AddressEncoding).Encode(a.Value)
}
```


## Consequences

### Backwards Compatibility

Since this update will affect all the instances of `AddressData` by completely changing how it is defined, such changes are backwards incompatible. For this reason, we need to make sure we write a proper migration to update all the current `AddressData` instances to the new `Address` type.

### Positive

- Easy to extend the address generation algorithm for `Address` instances

### Negative

### Neutral

## References

- [Cosmos address](https://docs.cosmos.network/master/architecture/adr-028-public-key-addresses.html#legacy-public-key-addresses-don-t-change)
- [Ethereum address](https://ethereum.org/en/developers/docs/accounts/#account-creation)
- [Solana address](https://docs.solana.com/terminology#account)
- [Elrond address](https://docs.elrond.com/technology/glossary/)
- [Polkadot address](https://wiki.polkadot.network/docs/learn-accounts#address-format)
- Issue [#724](https://github.com/desmos-labs/desmos/issues/724).

0 comments on commit d968175

Please sign in to comment.