Skip to content

Commit

Permalink
runtime: export abi_decode
Browse files Browse the repository at this point in the history
  • Loading branch information
evaporei committed Apr 5, 2021
1 parent 5d039ec commit 88154d8
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
20 changes: 19 additions & 1 deletion runtime/wasm/src/host_exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::{
UnresolvedContractCall,
};
use bytes::Bytes;
use ethabi::{encode, Address, Token};
use ethabi::param_type::{ParamType, Reader};
use ethabi::{decode, encode, Address, Token};
use graph::components::ethereum::*;
use graph::components::store::EntityKey;
use graph::components::subgraph::{ProofOfIndexingEvent, SharedProofOfIndexing};
Expand Down Expand Up @@ -816,6 +817,23 @@ pub(crate) fn abi_encode(params: Vec<Token>) -> Result<Vec<u8>, anyhow::Error> {
Ok(encode(&params))
}

pub(crate) fn abi_decode(mut types: String, data: Vec<u8>) -> Result<Vec<Token>, anyhow::Error> {
if !(types.starts_with('(') && types.ends_with(')')) {
return Err(anyhow::anyhow!("'ethabi' requires types to start and finish with parentheses, eg: '(uint256,address,(bytes32,int8,address))'"));
}

types.pop();
types.remove(0);

let param_types: Vec<ParamType> = types
.split(',')
.map(Reader::read)
.collect::<Result<_, _>>()
.or_else(|e| Err(anyhow::anyhow!("Failed to read types: {}", e)))?;

decode(&param_types, &data).map_err(|e| anyhow::anyhow!("Failed to decode: {}", e))
}

#[test]
fn test_string_to_h160_with_0x() {
assert_eq!(
Expand Down
14 changes: 14 additions & 0 deletions runtime/wasm/src/module/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ impl WasmInstance {
link!("log.log", log_log, level, msg_ptr);

link!("abi.encode", abi_encode, params_ptr);
link!("abi.decode", abi_decode, params_ptr, data_ptr);

link!("arweave.transactionData", arweave_transaction_data, ptr);

Expand Down Expand Up @@ -1402,6 +1403,19 @@ impl WasmInstanceContext {
.unwrap_or(Ok(AscPtr::null()))
}

/// function decode(types: String, data: Bytes): Array<ethereum.Value> | null
fn abi_decode(
&mut self,
types_ptr: AscPtr<AscString>,
data_ptr: AscPtr<Uint8Array>,
) -> Result<AscPtr<Array<AscPtr<AscEnum<EthereumValueKind>>>>, DeterministicHostError> {
let result = host_exports::abi_decode(self.asc_get(types_ptr)?, self.asc_get(data_ptr)?);
// return `null` if it fails
result
.map(|params| self.asc_new(&*params))
.unwrap_or(Ok(AscPtr::null()))
}

/// function arweave.transactionData(txId: string): Bytes | null
fn arweave_transaction_data(
&mut self,
Expand Down

0 comments on commit 88154d8

Please sign in to comment.