Skip to content

Commit

Permalink
Deprecating old functions (#1610)
Browse files Browse the repository at this point in the history
* Deprecating old functions

* Removing out of date section
  • Loading branch information
Braqzen authored May 19, 2022
1 parent 9e23221 commit a71f942
Show file tree
Hide file tree
Showing 10 changed files with 17 additions and 173 deletions.
6 changes: 0 additions & 6 deletions docs/src/reference/temporary_workarounds.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@

Storage variables of types `str[]`, `b256`, `enum`, and arrays are not yet supported. After [this issue](https://github.com/FuelLabs/sway/issues/1229) is closed, it will be possible to read and write these types using [manual storage management](../blockchain-development/storage.md#manual-storage-management). Moreover, storage mappings have to be managed manually for now as shown in the [Subcurrency](../examples/subcurrency.md) example.

## Serialization and Deserialization

Serialization/encoding of structures (Solidity's `abi.encode()` and `abi.encodePacked()`) is not yet implemented. Therefore, hashing an encoded struct is not possible without some manual work.

Serializing arbitrary structures can be accomplished manually by composition of recursive `hash_pair()` invocations. See the above example for hashing a pair of values.

## Optimizer

The optimizing pass of the compiler is not yet implemented, therefore bytecode will be more expensive and larger than it would be in production. Note that eventually the optimizer will support zero-cost abstractions, avoiding the need for developers to go down to inline assembly to produce optimal code.
Expand Down
13 changes: 1 addition & 12 deletions examples/hashing/src/main.sw
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
script;

use core::num::*;
use std::{hash::{HashMethod, hash_pair, hash_u64, hash_value, keccak256, sha256}, logging::log};
use std::{hash::{keccak256, sha256}, logging::log};

const VALUE_A = 0x9280359a3b96819889d30614068715d634ad0cf9bba70c0f430a8c201138f79f;

Expand Down Expand Up @@ -116,15 +116,4 @@ fn main() {
log(keccak_hashed_array);
log(keccak_hashed_enum);
log(keccak_hashed_struct);

// Hash a single u64 value.
let hashed_u64 = hash_u64(100, HashMethod::Sha256);

// Hash a single b256 value.
let hashed_b256 = hash_value(hashed_u64, HashMethod::Keccak256);

// Hash two b256 values.
let hashed_pair = hash_pair(hashed_b256, VALUE_A, HashMethod::Sha256);

log(hashed_pair);
}
8 changes: 4 additions & 4 deletions examples/subcurrency/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{
address::Address,
assert::assert,
chain::auth::{AuthError, Sender, msg_sender},
hash::*,
hash::sha256,
result::*,
revert::revert,
storage::{get, store}
Expand Down Expand Up @@ -73,7 +73,7 @@ impl Token for Contract {
};

// Increase the balance of receiver
let storage_slot = hash_pair(STORAGE_BALANCES, receiver.into(), HashMethod::Sha256);
let storage_slot = sha256((STORAGE_BALANCES, receiver.into()));
let mut receiver_amount = get::<u64>(storage_slot);
store(storage_slot, receiver_amount + amount);
}
Expand All @@ -87,13 +87,13 @@ impl Token for Contract {
};

// Reduce the balance of sender
let sender_storage_slot = hash_pair(STORAGE_BALANCES, sender.into(), HashMethod::Sha256);
let sender_storage_slot = sha256((STORAGE_BALANCES, sender.into()));
let mut sender_amount = get::<u64>(sender_storage_slot);
assert(sender_amount > amount);
store(sender_storage_slot, sender_amount - amount);

// Increase the balance of receiver
let receiver_storage_slot = hash_pair(STORAGE_BALANCES, receiver.into(), HashMethod::Sha256);
let receiver_storage_slot = sha256((STORAGE_BALANCES, receiver.into()));
let mut receiver_amount = get::<u64>(receiver_storage_slot);
store(receiver_storage_slot, receiver_amount + amount);
}
Expand Down
4 changes: 2 additions & 2 deletions sway-fmt/src/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ fn one_liner() -> bool {
let test_sway = r#"script;
use std::chain::{panic,log_u8};
use std::chain::assert;
use std::hash::{HashMethod, hash_value, hash_pair };
use std::hash::{sha256, keccak256 };
use a::b::{c,d::{f,e}};
use a::b::{c,d::{f,self}};
Expand All @@ -665,7 +665,7 @@ fn main() {
let expected_sway = r#"script;
use std::chain::{log_u8, panic};
use std::chain::assert;
use std::hash::{HashMethod, hash_pair, hash_value};
use std::hash::{keccak256, sha256};
use a::b::{c, d::{e, f}};
use a::b::{c, d::{self, f}};
Expand Down
4 changes: 2 additions & 2 deletions sway-lib-std/src/ecr.sw
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ library ecr;
use ::address::Address;
use ::b512::B512;
use ::context::registers::error;
use ::hash::{HashMethod, hash_pair};
use ::hash::sha256;
use ::result::*;

pub enum EcRecoverError {
Expand Down Expand Up @@ -36,7 +36,7 @@ pub fn ec_recover_address(signature: B512, msg_hash: b256) -> Result<Address, Ec
Result::Err(e)
} else {
let pub_key = pub_key_result.unwrap();
let address = hash_pair((pub_key.bytes)[0], (pub_key.bytes)[1], HashMethod::Sha256);
let address = sha256(((pub_key.bytes)[0], (pub_key.bytes)[1]));
Result::Ok(~Address::from(address))
}
}
115 changes: 0 additions & 115 deletions sway-lib-std/src/hash.sw
Original file line number Diff line number Diff line change
Expand Up @@ -12,121 +12,6 @@ pub fn not(a: bool) -> bool {
}
}

pub enum HashMethod {
Sha256: (),
Keccak256: (),
}

impl HashMethod {
fn eq(self, other: Self) -> bool {
// Enum instantiations are on the stack, so we can use MEQ in this case to just compare the
// tag in the variant (and ignore the unit values).
asm(r1: self, r2: other, r3, r4) {
addi r3 zero i8;
meq r4 r1 r2 r3;
r4: bool
}
}
}

pub fn hash_u64(value: u64, method: HashMethod) -> b256 {
if method.eq(HashMethod::Sha256) {
asm(r1: value, hashed_b256_ptr, r3, value_ptr) {
// put the u64 on the stack
move value_ptr sp;
cfei i8;
sw value_ptr r1 i0;
move hashed_b256_ptr sp;
cfei i32;
addi r3 zero i8; // hash eight bytes since a u64 is eight bytes
s256 hashed_b256_ptr value_ptr r3;
hashed_b256_ptr: b256
}
} else {
asm(r1: value, hashed_b256_ptr, r3, value_ptr) {
// put the u64 on the stack
move value_ptr sp;
cfei i8;
sw value_ptr r1 i0;
move hashed_b256_ptr sp;
cfei i32;
addi r3 zero i8; // hash eight bytes since a u64 is eight bytes
k256 hashed_b256_ptr value_ptr r3;
hashed_b256_ptr: b256
}
}
}

pub fn hash_value(value: b256, method: HashMethod) -> b256 {
// Use pattern matching for method when we can...
// NOTE: Deliberately using Sha256 here and Keccak256 below to avoid 'never constructed
// warning'.
if method.eq(HashMethod::Sha256) {
asm(r1: value, r2, r3) {
move r2 sp;
cfei i32;
addi r3 zero i32;
s256 r2 r1 r3;
r2: b256
}
} else {
asm(r1: value, r2, r3) {
move r2 sp;
cfei i32;
addi r3 zero i32;
k256 r2 r1 r3;
r2: b256
}
}
}

pub fn hash_pair(value_a: b256, value_b: b256, method: HashMethod) -> b256 {
// Use pattern matching for method when we can...
// NOTE: Deliberately using Keccak256 here and Sha256 above to avoid 'never constructed
// warning'.
// TODO: Avoid the code duplication? Ideally this conditional would be tightly wrapped around
// the S256 and K256 instructions but we'd need control flow within ASM blocks to allow that.
if method.eq(HashMethod::Keccak256) {
asm(r1: value_a, r2: value_b, r3, r4, r5, r6) {
move r3 sp; // Result buffer.
cfei i32;
move r4 sp; // Buffer for copies of value_a and value_b.
cfei i64;

addi r5 zero i32;
mcp r4 r1 r5; // Copy 32 bytes to buffer.
addi r6 r4 i32;
mcp r6 r2 r5; // Append 32 bytes to buffer.

addi r5 r5 i32;
k256 r3 r4 r5; // Hash 64 bytes to the result buffer.

cfsi i64; // Free the copies buffer.

r3: b256
}
} else {
asm(r1: value_a, r2: value_b, r3, r4, r5, r6) {
move r3 sp; // Result buffer.
cfei i32;
move r4 sp; // Buffer for copies of value_a and value_b.
cfei i64;

addi r5 zero i32;
mcp r4 r1 r5; // Copy 32 bytes to buffer.
addi r6 r4 i32;
mcp r6 r2 r5; // Append 32 bytes to buffer.

addi r5 r5 i32;
s256 r3 r4 r5; // Hash 64 bytes to the result buffer.

cfsi i64; // Free the copies buffer.

r3: b256
}
}
}

/// Returns the SHA-2-256 hash of `param`.
pub fn sha256<T>(param: T) -> b256 {
let mut result_buffer: b256 = ~b256::min();
Expand Down
4 changes: 2 additions & 2 deletions sway-lib-std/src/vm/evm/ecr.sw
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ::address::Address;
use ::b512::B512;
use ::context::registers::error;
use ::ecr::{EcRecoverError, ec_recover};
use ::hash::{HashMethod, hash_pair};
use ::hash::keccak256;
use ::result::*;

/// Recover the address derived from the private key used to sign a message.
Expand All @@ -20,7 +20,7 @@ pub fn ec_recover_address(signature: B512, msg_hash: b256) -> Result<Address, Ec
let pub_key = pub_key_result.unwrap();

// Note that Ethereum addresses are derived from the Keccak256 hash of the pubkey (not sha256)
let address = hash_pair((pub_key.bytes)[0], (pub_key.bytes)[1], HashMethod::Keccak256);
let address = keccak256(((pub_key.bytes)[0], (pub_key.bytes)[1]));

// Zero out first 12 bytes for ethereum address
asm(r1: address) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
script;

use std::hash::{HashMethod, hash_value, hash_pair};
use std::hash::{keccak256, sha256};

fn main() -> u64 {
let aaaa = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
Expand All @@ -12,13 +12,13 @@ fn main() -> u64 {
1
} else if !(aaaa == aaaa) {
2
} else if !(hash_value(aaaa, HashMethod::Sha256) == 0xe0e77a507412b120f6ede61f62295b1a7b2ff19d3dcc8f7253e51663470c888e) {
} else if !(sha256(aaaa) == 0xe0e77a507412b120f6ede61f62295b1a7b2ff19d3dcc8f7253e51663470c888e) {
3
} else if !(hash_value(aaaa, HashMethod::Keccak256) == 0x20ee8f1366f06926e9e8771d8fb9007a8537c8dfdb6a3f8c2cfd64db19d2ec90) {
} else if !(keccak256(aaaa) == 0x20ee8f1366f06926e9e8771d8fb9007a8537c8dfdb6a3f8c2cfd64db19d2ec90) {
4
} else if !(hash_pair(aaaa, abaa, HashMethod::Sha256) == 0xa4bca8eb8f338f7fda26960fa43bfe34fbc562e2ee0d7c6e8856c1c587f215ce) {
} else if !(sha256((aaaa, abaa)) == 0xa4bca8eb8f338f7fda26960fa43bfe34fbc562e2ee0d7c6e8856c1c587f215ce) {
5
} else if !(hash_pair(aaaa, abaa, HashMethod::Keccak256) == 0x4fce5a297040d82eecf7b0ae4855ad43698f191ee38820e27748648765bc42bd) {
} else if !(keccak256((aaaa, abaa)) == 0x4fce5a297040d82eecf7b0ae4855ad43698f191ee38820e27748648765bc42bd) {
6
} else {
100
Expand Down
13 changes: 0 additions & 13 deletions test/src/sdk-harness/test_projects/hashing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,6 @@ async fn get_hashing_instance() -> (HashingTestContract, ContractId) {
(instance, id)
}

#[tokio::test]
async fn test_hash_u64() {
let (instance, _id) = get_hashing_instance().await;
// Check that hashing the same `u64` results in the same hash
let sha256_result1 = instance.get_s256_hash_u64(42).call().await.unwrap();
let sha256_result2 = instance.get_s256_hash_u64(42).call().await.unwrap();
assert_eq!(sha256_result1.value, sha256_result2.value);

let keccak256_result1 = instance.get_k256_hash_u64(42).call().await.unwrap();
let keccak256_result2 = instance.get_k256_hash_u64(42).call().await.unwrap();
assert_eq!(keccak256_result1.value, keccak256_result2.value);
}

mod sha256 {

use super::*;
Expand Down
13 changes: 1 addition & 12 deletions test/src/sdk-harness/test_projects/hashing/src/main.sw
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
contract;

use std::hash::{HashMethod, hash_u64, keccak256, sha256};
use std::hash::{keccak256, sha256};
use core::num::*;

abi MyContract {
Expand All @@ -27,9 +27,6 @@ abi MyContract {
fn keccak256_array(value1: u64, value2: u64) -> b256;
fn keccak256_enum(location: bool) -> b256;
fn keccak256_struct(location: bool) -> b256;

fn get_s256_hash_u64(value: u64) -> b256;
fn get_k256_hash_u64(value: u64) -> b256;
}

enum Location {
Expand Down Expand Up @@ -167,12 +164,4 @@ impl MyContract for Contract {
alive: true, random_b256: ~b256::min()
})
}

fn get_s256_hash_u64(value: u64) -> b256 {
hash_u64(value, HashMethod::Sha256)
}

fn get_k256_hash_u64(value: u64) -> b256 {
hash_u64(value, HashMethod::Keccak256)
}
}

0 comments on commit a71f942

Please sign in to comment.