Skip to content

Commit

Permalink
Merge pull request #802 from CosmWasm/primary-address
Browse files Browse the repository at this point in the history
Thoughts on addresses
  • Loading branch information
mergify[bot] authored Apr 7, 2021
2 parents 167875c + e5271a9 commit 0413557
Show file tree
Hide file tree
Showing 92 changed files with 1,395 additions and 1,126 deletions.
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ and this project adheres to
returns "submessages" (above). ([#796])
- cosmwasm-std: Implement `From<Uint128> for String`, `From<Uint128> for u128`
as well as `From<u{32,16,8}> for Uint128`.
- cosmwasm-std: Create new address type `Addr`. This is human readable (like
`HumanAddr`) but is immutable and always contains a valid address ([#802]).
- cosmwasm-std: Replace `HumanAddr` with `String` in `BankQuery`, `StakingQuery`
and `WasmQuery` query requests.
- cosmwasm-vm: Add import `addr_validate` ([#802]).

[#692]: https://github.com/CosmWasm/cosmwasm/issues/692
[#706]: https://github.com/CosmWasm/cosmwasm/pull/706
Expand All @@ -62,6 +67,7 @@ and this project adheres to
[#768]: https://github.com/CosmWasm/cosmwasm/pull/768
[#793]: https://github.com/CosmWasm/cosmwasm/pull/793
[#796]: https://github.com/CosmWasm/cosmwasm/pull/796
[#802]: https://github.com/CosmWasm/cosmwasm/pull/802

### Changed

Expand Down Expand Up @@ -106,10 +112,18 @@ and this project adheres to
- cosmwasm-std: Rename type `KV` to `Pair` in order to comply to naming
convention as enforced by clippy rule `upper_case_acronyms` from Rust 1.51.0
on.
- cosmwasm-std: `ContractInfo::address` and `MessageInfo::sender` are now of
type `Addr`. The value of those fields is created by the host and thus valid.
- cosmwasm-vm: Bump required marker export `cosmwasm_vm_version_4` to
`interface_version_5`.
- cosmwasm-vm: Rename trait `Api` to `BackendApi` to better express this is the
API provided by the VM's backend (i.e. the blockchain).
- cosmwasm-vm: Rename imports to `addr_canonicalize` and `addr_humanize`
([#802]).
- cosmwasm-vm: Replace types `HumanAddr`/`CanonicalAddr` with
`&str`/`String`/`&[u8]`/`Vec<u8>` in the methods of `BackendApi`. The address
types belong in the contract development and the backend operates on raw
strings and binary anyways.
- contracts: `reflect` contract requires `stargate` feature and supports
redispatching `Stargate` and `IbcMsg::Transfer` messages ([#692])
- cosmwasm-std: The arithmetic methods of `Uint128` got a huge overhaul, making
Expand All @@ -131,6 +145,10 @@ and this project adheres to
library. Please use the explicit `*_sub` methods introduced above. In a
couple of releases from now, we want to introduce the operator again with
panicking overflow behaviour ([#858]).
- cosmwasm-std: Change address types in `BankMsg`, `IbcMsg` and `WasmMsg` from
`HumanAddr` to `String` ([#802]).
- cosmwasm-std: `Api::addr_humanize` now returns `Addr` instead of `HumanAddr`
([#802]).

[#696]: https://github.com/CosmWasm/cosmwasm/issues/696
[#697]: https://github.com/CosmWasm/cosmwasm/issues/697
Expand All @@ -140,13 +158,20 @@ and this project adheres to
[#853]: https://github.com/CosmWasm/cosmwasm/pull/853
[#858]: https://github.com/CosmWasm/cosmwasm/issues/858
[u128]: https://doc.rust-lang.org/std/primitive.u128.html
[#802]: https://github.com/CosmWasm/cosmwasm/pull/802

### Deprecated

- cosmwasm-std: `InitResponse`, `MigrateResponse` and `HandleResponse` are
deprecated in favour of the new `Response`.
- cosmwasm-std: `Context` is deprecated in favour of the new mutable helpers in
`Response`.
- cosmwasm-std: `HumanAddr` is not much more than an alias to `String` and it
does not provide significant safety advantages. With CosmWasm 0.14, we now use
`String` when there was `HumanAddr` before. There is also the new `Addr`,
which holds a validated immutable human readable address. ([#802])

[#802]: https://github.com/CosmWasm/cosmwasm/pull/802

## [0.13.2] - 2021-01-14

Expand Down
74 changes: 74 additions & 0 deletions MIGRATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,80 @@ major releases of `cosmwasm`. Note that you can also view the
- If necessary, add a wildcard arm to the `match` of now non-exhaustive message
types `BankMsg`, `BankQuery`, `WasmMsg` and `WasmQuery`.

- `HumanAddr` has been deprecated in favour of simply `String`. It never added
any significant safety bonus over `String` and was just a marker type. The new
type `Addr` was created to hold validated addresses. Those can be created via
`Addr::unchecked`, `Api::addr_validate`, `Api::addr_humanize` and JSON
deserialization. In order to maintain type safety, deserialization into `Addr`
must only be done from trusted sources like a contract's state or a query
response. User inputs must be deserialized into `String`. This new `Addr` type
makes it easy to use human readable addresses in state:

With pre-validated `Addr` from `MessageInfo`:

```rust
// before
pub struct State {
pub owner: CanonicalAddr,
}

let state = State {
owner: deps.api.canonical_address(&info.sender /* of type HumanAddr */)?,
};


// after
pub struct State {
pub owner: Addr,
}
let state = State {
owner: info.sender.clone() /* of type Addr */,
};
```

With user input in `msg`:

```rust
// before
pub struct State {
pub verifier: CanonicalAddr,
pub beneficiary: CanonicalAddr,
pub funder: CanonicalAddr,
}

deps.storage.set(
CONFIG_KEY,
&to_vec(&State {
verifier: deps.api.canonical_address(&msg.verifier /* of type HumanAddr */)?,
beneficiary: deps.api.canonical_address(&msg.beneficiary /* of type HumanAddr */)?,
funder: deps.api.canonical_address(&info.sender /* of type HumanAddr */)?,
})?,
);

// after
pub struct State {
pub verifier: Addr,
pub beneficiary: Addr,
pub funder: Addr,
}

deps.storage.set(
CONFIG_KEY,
&to_vec(&State {
verifier: deps.api.addr_validate(&msg.verifier /* of type String */)?,
beneficiary: deps.api.addr_validate(&msg.beneficiary /* of type String */)?,
funder: info.sender /* of type Addr */,
})?,
);
```

The existing `CanonicalAddr` remains unchanged and can be used in cases in
which a compact binary representation is desired. For JSON state this does not
save much data (e.g. the bech32 address
cosmos1pfq05em6sfkls66ut4m2257p7qwlk448h8mysz takes 45 bytes as direct ASCII
and 28 bytes when its canonical representation is base64 encoded). For fixed
length database keys `CanonicalAddr` remains handy though.

## 0.12 -> 0.13

- The minimum Rust supported version for 0.13 is 1.47.0. Verify your Rust
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,9 @@ extern "C" {
#[cfg(feature = "iterator")]
fn db_next(iterator_id: u32) -> u32;

fn canonicalize_address(source: u32, destination: u32) -> u32;
fn humanize_address(source: u32, destination: u32) -> u32;
fn addr_validate(source_ptr: u32) -> u32;
fn addr_canonicalize(source: u32, destination: u32) -> u32;
fn addr_humanize(source: u32, destination: u32) -> u32;

/// Verifies message hashes against a signature with a public key, using the
/// secp256k1 ECDSA parametrization.
Expand Down
5 changes: 0 additions & 5 deletions contracts/burner/schema/migrate_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@
],
"properties": {
"payout": {
"$ref": "#/definitions/HumanAddr"
}
},
"definitions": {
"HumanAddr": {
"type": "string"
}
}
Expand Down
6 changes: 3 additions & 3 deletions contracts/burner/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub fn migrate(deps: DepsMut, env: Env, msg: MigrateMsg) -> StdResult<Response>
}

// get balance and send all to recipient
let balance = deps.querier.query_all_balances(&env.contract.address)?;
let balance = deps.querier.query_all_balances(env.contract.address)?;
let send = BankMsg::Send {
to_address: msg.payout.clone(),
amount: balance,
Expand All @@ -50,7 +50,7 @@ pub fn migrate(deps: DepsMut, env: Env, msg: MigrateMsg) -> StdResult<Response>
mod tests {
use super::*;
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
use cosmwasm_std::{coins, HumanAddr, StdError, Storage};
use cosmwasm_std::{coins, StdError, Storage};

#[test]
fn instantiate_fails() {
Expand Down Expand Up @@ -80,7 +80,7 @@ mod tests {
assert_eq!(3, cnt);

// change the verifier via migrate
let payout = HumanAddr::from("someone else");
let payout = String::from("someone else");
let msg = MigrateMsg {
payout: payout.clone(),
};
Expand Down
4 changes: 1 addition & 3 deletions contracts/burner/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use cosmwasm_std::HumanAddr;

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct MigrateMsg {
pub payout: HumanAddr,
pub payout: String,
}

/// A placeholder where we don't take any input
Expand Down
4 changes: 2 additions & 2 deletions contracts/burner/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//! });
//! 4. Anywhere you see query(&deps, ...) you must replace it with query(&mut deps, ...)

use cosmwasm_std::{coins, BankMsg, ContractResult, HumanAddr, Order, Response};
use cosmwasm_std::{coins, BankMsg, ContractResult, Order, Response};
use cosmwasm_vm::testing::{instantiate, migrate, mock_env, mock_info, mock_instance};

use burner::msg::{InstantiateMsg, MigrateMsg};
Expand Down Expand Up @@ -60,7 +60,7 @@ fn migrate_cleans_up_data() {
.unwrap();

// change the verifier via migrate
let payout = HumanAddr::from("someone else");
let payout = String::from("someone else");
let msg = MigrateMsg {
payout: payout.clone(),
};
Expand Down
10 changes: 6 additions & 4 deletions contracts/hackatom/examples/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@ use std::fs::create_dir_all;
use cosmwasm_schema::{export_schema, remove_schemas, schema_for};
use cosmwasm_std::BalanceResponse;

use hackatom::contract::{
ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, State, SudoMsg, VerifierResponse,
};
use hackatom::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, SudoMsg, VerifierResponse};
use hackatom::state::State;

fn main() {
let mut out_dir = current_dir().unwrap();
out_dir.push("schema");
create_dir_all(&out_dir).unwrap();
remove_schemas(&out_dir).unwrap();

// messages
export_schema(&schema_for!(InstantiateMsg), &out_dir);
export_schema(&schema_for!(ExecuteMsg), &out_dir);
export_schema(&schema_for!(MigrateMsg), &out_dir);
export_schema(&schema_for!(SudoMsg), &out_dir);
export_schema(&schema_for!(QueryMsg), &out_dir);
export_schema(&schema_for!(State), &out_dir);
export_schema(&schema_for!(VerifierResponse), &out_dir);
export_schema(&schema_for!(BalanceResponse), &out_dir);

// state
export_schema(&schema_for!(State), &out_dir);
}
7 changes: 1 addition & 6 deletions contracts/hackatom/schema/instantiate_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,9 @@
],
"properties": {
"beneficiary": {
"$ref": "#/definitions/HumanAddr"
"type": "string"
},
"verifier": {
"$ref": "#/definitions/HumanAddr"
}
},
"definitions": {
"HumanAddr": {
"type": "string"
}
}
Expand Down
5 changes: 0 additions & 5 deletions contracts/hackatom/schema/migrate_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@
],
"properties": {
"verifier": {
"$ref": "#/definitions/HumanAddr"
}
},
"definitions": {
"HumanAddr": {
"type": "string"
}
}
Expand Down
9 changes: 2 additions & 7 deletions contracts/hackatom/schema/query_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
],
"properties": {
"address": {
"$ref": "#/definitions/HumanAddr"
"type": "string"
}
}
}
Expand Down Expand Up @@ -65,10 +65,5 @@
},
"additionalProperties": false
}
],
"definitions": {
"HumanAddr": {
"type": "string"
}
}
]
}
13 changes: 5 additions & 8 deletions contracts/hackatom/schema/state.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,19 @@
],
"properties": {
"beneficiary": {
"$ref": "#/definitions/CanonicalAddr"
"$ref": "#/definitions/Addr"
},
"funder": {
"$ref": "#/definitions/CanonicalAddr"
"$ref": "#/definitions/Addr"
},
"verifier": {
"$ref": "#/definitions/CanonicalAddr"
"$ref": "#/definitions/Addr"
}
},
"definitions": {
"Binary": {
"description": "Binary is a wrapper around Vec<u8> to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec<u8>",
"Addr": {
"description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.",
"type": "string"
},
"CanonicalAddr": {
"$ref": "#/definitions/Binary"
}
}
}
5 changes: 1 addition & 4 deletions contracts/hackatom/schema/sudo_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
}
},
"recipient": {
"$ref": "#/definitions/HumanAddr"
"type": "string"
}
}
}
Expand All @@ -47,9 +47,6 @@
}
}
},
"HumanAddr": {
"type": "string"
},
"Uint128": {
"type": "string"
}
Expand Down
5 changes: 0 additions & 5 deletions contracts/hackatom/schema/verifier_response.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@
],
"properties": {
"verifier": {
"$ref": "#/definitions/HumanAddr"
}
},
"definitions": {
"HumanAddr": {
"type": "string"
}
}
Expand Down
Loading

0 comments on commit 0413557

Please sign in to comment.