1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use crate::crypto;
use crate::error::InterpreterError;
use fuel_tx::crypto::Hasher;
use fuel_tx::{Transaction, ValidationError};
use fuel_types::{Bytes32, ContractId, Salt};
use std::cmp;
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde-types", derive(serde::Serialize, serde::Deserialize))]
pub struct Contract(Vec<u8>);
impl Contract {
pub fn root(&self) -> Bytes32 {
let root = self.0.chunks(8).map(|c| {
let mut bytes = [0u8; 8];
let l = cmp::min(c.len(), 8);
(&mut bytes[..l]).copy_from_slice(c);
bytes
});
crypto::ephemeral_merkle_root(root)
}
pub fn id(&self, salt: &Salt, root: &Bytes32) -> ContractId {
let mut hasher = Hasher::default();
hasher.input(ContractId::SEED);
hasher.input(salt);
hasher.input(root);
ContractId::from(*hasher.digest())
}
}
impl From<Vec<u8>> for Contract {
fn from(c: Vec<u8>) -> Self {
Self(c)
}
}
impl From<&[u8]> for Contract {
fn from(c: &[u8]) -> Self {
Self(c.into())
}
}
impl From<&mut [u8]> for Contract {
fn from(c: &mut [u8]) -> Self {
Self(c.into())
}
}
impl From<Contract> for Vec<u8> {
fn from(c: Contract) -> Vec<u8> {
c.0
}
}
impl AsRef<[u8]> for Contract {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl AsMut<[u8]> for Contract {
fn as_mut(&mut self) -> &mut [u8] {
self.0.as_mut()
}
}
impl TryFrom<&Transaction> for Contract {
type Error = InterpreterError;
fn try_from(tx: &Transaction) -> Result<Self, Self::Error> {
match tx {
Transaction::Create {
bytecode_witness_index,
witnesses,
..
} => witnesses
.get(*bytecode_witness_index as usize)
.map(|c| c.as_ref().into())
.ok_or_else(|| ValidationError::TransactionCreateBytecodeWitnessIndex.into()),
_ => Err(ValidationError::TransactionScriptOutputContractCreated { index: 0 }.into()),
}
}
}