1 | import {
|
2 | assertContractParameterType,
|
3 | common,
|
4 | ContractJSON,
|
5 | IOHelper,
|
6 | JSONHelper,
|
7 | toJSONContractParameterType,
|
8 | UInt160,
|
9 | } from '@neo-one/client-common-esnext-esm';
|
10 | import { assertContractPropertyState, ContractModel } from '@neo-one/client-full-common-esnext-esm';
|
11 | import { ContractParameterType } from './contractParameter';
|
12 | import { ContractPropertyState } from './ContractPropertyState';
|
13 | import { Equals, EquatableKey } from './Equatable';
|
14 | import {
|
15 | DeserializeWireBaseOptions,
|
16 | DeserializeWireOptions,
|
17 | SerializableJSON,
|
18 | SerializeJSONContext,
|
19 | } from './Serializable';
|
20 | import { BinaryReader, utils } from './utils';
|
21 |
|
22 | export interface ContractKey {
|
23 | readonly hash: UInt160;
|
24 | }
|
25 | export interface ContractAdd {
|
26 | readonly hash?: UInt160;
|
27 | readonly version?: number;
|
28 | readonly script: Buffer;
|
29 | readonly parameterList: ReadonlyArray<ContractParameterType>;
|
30 | readonly returnType: ContractParameterType;
|
31 | readonly contractProperties: ContractPropertyState;
|
32 | readonly name: string;
|
33 | readonly codeVersion: string;
|
34 | readonly author: string;
|
35 | readonly email: string;
|
36 | readonly description: string;
|
37 | }
|
38 |
|
39 | export class Contract extends ContractModel implements SerializableJSON<ContractJSON>, EquatableKey {
|
40 | public static deserializeWireBase(options: DeserializeWireBaseOptions): Contract {
|
41 | return deserializeContractWireBase({
|
42 | context: options.context,
|
43 | reader: options.reader,
|
44 | });
|
45 | }
|
46 |
|
47 | public static deserializeWire(options: DeserializeWireOptions): Contract {
|
48 | return this.deserializeWireBase({
|
49 | context: options.context,
|
50 | reader: new BinaryReader(options.buffer),
|
51 | });
|
52 | }
|
53 |
|
54 | public readonly equals: Equals = utils.equals(Contract, this, (other) => common.uInt160Equal(this.hash, other.hash));
|
55 | public readonly toKeyString = utils.toKeyString(Contract, () => this.hashHex);
|
56 | private readonly contractSizeInternal = utils.lazy(() =>
|
57 | sizeOfContract({
|
58 | script: this.script,
|
59 | parameterList: this.parameterList,
|
60 | name: this.name,
|
61 | codeVersion: this.codeVersion,
|
62 | author: this.author,
|
63 | email: this.email,
|
64 | description: this.description,
|
65 | }),
|
66 | );
|
67 |
|
68 | public get size(): number {
|
69 | return this.contractSizeInternal();
|
70 | }
|
71 |
|
72 | public serializeJSON(_context: SerializeJSONContext): ContractJSON {
|
73 | return {
|
74 | version: this.version,
|
75 | hash: JSONHelper.writeUInt160(this.hash),
|
76 | script: JSONHelper.writeBuffer(this.script),
|
77 | parameters: this.parameterList.map(toJSONContractParameterType),
|
78 |
|
79 | returntype: toJSONContractParameterType(this.returnType),
|
80 | name: this.name,
|
81 | code_version: this.codeVersion,
|
82 | author: this.author,
|
83 | email: this.email,
|
84 | description: this.description,
|
85 | properties: {
|
86 | storage: this.hasStorage,
|
87 | dynamic_invoke: this.hasDynamicInvoke,
|
88 | payable: this.payable,
|
89 | },
|
90 | };
|
91 | }
|
92 | }
|
93 |
|
94 | export const sizeOfContract = ({
|
95 | script,
|
96 | parameterList,
|
97 | name,
|
98 | codeVersion,
|
99 | author,
|
100 | email,
|
101 | description,
|
102 | publishVersion,
|
103 | }: {
|
104 | readonly script: Buffer;
|
105 | readonly parameterList: ReadonlyArray<ContractParameterType>;
|
106 | readonly name: string;
|
107 | readonly codeVersion: string;
|
108 | readonly author: string;
|
109 | readonly email: string;
|
110 | readonly description: string;
|
111 | readonly publishVersion?: number;
|
112 | }) =>
|
113 | IOHelper.sizeOfVarBytesLE(script) +
|
114 | IOHelper.sizeOfVarBytesLE(Buffer.from(parameterList as ContractParameterType[])) +
|
115 | IOHelper.sizeOfUInt8 +
|
116 | (publishVersion === undefined ? IOHelper.sizeOfBoolean : 0) +
|
117 | IOHelper.sizeOfVarString(name) +
|
118 | IOHelper.sizeOfVarString(codeVersion) +
|
119 | IOHelper.sizeOfVarString(author) +
|
120 | IOHelper.sizeOfVarString(email) +
|
121 | IOHelper.sizeOfVarString(description);
|
122 |
|
123 | export const deserializeContractWireBase = ({
|
124 | reader,
|
125 | publishVersion,
|
126 | }: {
|
127 | readonly publishVersion?: number;
|
128 | } & DeserializeWireBaseOptions): Contract => {
|
129 | const script = reader.readVarBytesLE();
|
130 | const parameterList = [...reader.readVarBytesLE()].map(assertContractParameterType);
|
131 |
|
132 | const returnType = assertContractParameterType(reader.readUInt8());
|
133 | const contractProperties =
|
134 | publishVersion === undefined || publishVersion >= 1
|
135 | ? assertContractPropertyState(reader.readUInt8())
|
136 | : ContractPropertyState.NoProperty;
|
137 | const name = reader.readVarString(252);
|
138 | const codeVersion = reader.readVarString(252);
|
139 | const author = reader.readVarString(252);
|
140 | const email = reader.readVarString(252);
|
141 | const description = reader.readVarString(65536);
|
142 |
|
143 | return new Contract({
|
144 | script,
|
145 | parameterList,
|
146 | returnType,
|
147 | contractProperties,
|
148 | name,
|
149 | codeVersion,
|
150 | author,
|
151 | email,
|
152 | description,
|
153 | });
|
154 | };
|