Skip to content

Commit

Permalink
Merge pull request #383 from multiversx/address-01
Browse files Browse the repository at this point in the history
Address wrt. specs (partially). Additional minor breaking changes.
  • Loading branch information
andreibancioiu committed Feb 16, 2024
2 parents 871d952 + 42498c3 commit eca0221
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class Account {
/**
* The address of the account.
*/
readonly address: IAddress = new Address();
readonly address: IAddress = Address.empty();

/**
* The nonce of the account (the account sequence number).
Expand Down
14 changes: 13 additions & 1 deletion src/address.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe("test address", () => {
});

it("should create empty address", async () => {
let nobody = new Address();
const nobody = Address.empty();

assert.isEmpty(nobody.hex());
assert.isEmpty(nobody.bech32());
Expand Down Expand Up @@ -55,4 +55,16 @@ describe("test address", () => {
assert.isFalse(Address.isValid("xerd1l453hd0gt5gzdp7czpuall8ggt2dcv5zwmfdf3sd3lguxseux2fsmsgldz"));
assert.isFalse(Address.isValid("erd1l453hd0gt5gzdp7czpuall8ggt2dcv5zwmfdf3sd3lguxseux2"));
});

it("should check whether isSmartContract", () => {
assert.isFalse(
Address.fromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th").isSmartContract(),
);
assert.isTrue(
Address.fromBech32("erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqplllst77y4l").isSmartContract(),
);
assert.isTrue(
Address.fromBech32("erd1qqqqqqqqqqqqqpgqxwakt2g7u9atsnr03gqcgmhcv38pt7mkd94q6shuwt").isSmartContract(),
);
});
});
69 changes: 55 additions & 14 deletions src/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class Address {
/**
* Creates an address object, given a raw string (whether a hex pubkey or a Bech32 address), a sequence of bytes, or another Address object.
*/
public constructor(value?: Address | Buffer | string) {
public constructor(value: Address | Buffer | string) {
if (!value) {
return;
}
Expand All @@ -48,7 +48,7 @@ export class Address {
}

private static fromValidHex(value: string): Address {
let result = new Address();
let result = Address.empty();
result.valueHex = value;
return result;
}
Expand Down Expand Up @@ -91,10 +91,11 @@ export class Address {
}

/**
* Creates an empty address object
* Creates an empty address object.
* Generally speaking, this should not be used by client code (internal use only).
*/
static empty(): Address {
return new Address();
return new Address("");
}

/**
Expand All @@ -109,12 +110,12 @@ export class Address {
throw new errors.ErrAddressCannotCreate(value, err);
}

let prefix = decoded.prefix;
const prefix = decoded.prefix;
if (prefix != HRP) {
throw new errors.ErrAddressBadHrp(HRP, prefix);
}

let pubkey = Buffer.from(bech32.fromWords(decoded.words));
const pubkey = Buffer.from(bech32.fromWords(decoded.words));
if (pubkey.length != PUBKEY_LENGTH) {
throw new errors.ErrAddressCannotCreate(value);
}
Expand All @@ -138,9 +139,16 @@ export class Address {
}

/**
* Returns the hex representation of the address (pubkey)
* Use {@link toHex} instead.
*/
hex(): string {
return this.toHex();
}

/**
* Returns the hex representation of the address (pubkey)
*/
toHex(): string {
if (this.isEmpty()) {
return "";
}
Expand All @@ -149,9 +157,16 @@ export class Address {
}

/**
* Returns the bech32 representation of the address
* Use {@link toBech32} instead.
*/
bech32(): string {
return this.toBech32();
}

/**
* Returns the bech32 representation of the address
*/
toBech32(): string {
if (this.isEmpty()) {
return "";
}
Expand All @@ -162,16 +177,31 @@ export class Address {
}

/**
* Returns the pubkey as raw bytes (buffer)
* Use {@link getPublicKey} instead.
*/
pubkey(): Buffer {
return this.getPublicKey();
}

/**
* Returns the pubkey as raw bytes (buffer)
*/
getPublicKey(): Buffer {
if (this.isEmpty()) {
return Buffer.from([]);
}

return Buffer.from(this.valueHex, "hex");
}

/**
* Returns the human-readable-part of the bech32 addresses.
* The HRP is currently hardcoded to "erd".
*/
getHrp(): string {
return HRP;
}

/**
* Returns whether the address is empty.
*/
Expand All @@ -194,27 +224,38 @@ export class Address {
* Returns the bech32 representation of the address
*/
toString(): string {
return this.bech32();
return this.toBech32();
}

/**
* Converts the address to a pretty, plain JavaScript object.
*/
toJSON(): object {
return {
bech32: this.bech32(),
pubkey: this.hex(),
bech32: this.toBech32(),
pubkey: this.toHex(),
};
}

/**
* Creates the Zero address (the one that should be used when deploying smart contracts)
* Creates the Zero address (the one that should be used when deploying smart contracts).
* Generally speaking, this should not be used by client code (internal use only).
*/
static Zero(): Address {
return new Address("0".repeat(64));
}

/**
* Use {@link isSmartContract} instead.
*/
isContractAddress(): boolean {
return this.hex().startsWith(SMART_CONTRACT_HEX_PUBKEY_PREFIX);
return this.isSmartContract();
}

/**
* Returns whether the address is a smart contract address.
*/
isSmartContract(): boolean {
return this.toHex().startsWith(SMART_CONTRACT_HEX_PUBKEY_PREFIX);
}
}
11 changes: 3 additions & 8 deletions src/compatibility.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
import { Address } from "./address";
import { Err } from "./errors";
import { IAddress } from "./interface";

/**
* For internal use only.
*/
export class Compatibility {
static areWarningsEnabled: boolean = true;

/**
* For internal use only.
*/
static guardAddressIsSetAndNonZero(address: IAddress | undefined, context: string, resolution: string) {
if (!this.areWarningsEnabled) {
return;
}

if (!address || address.bech32() == "") {
console.warn(
throw new Err(
`${context}: address should be set; ${resolution}. In the future, this will throw an exception instead of emitting a WARN.`,
);
} else if (address.bech32() == Address.Zero().bech32()) {
console.warn(
throw new Err(
`${context}: address should not be the 'zero' address (also known as the 'contracts deployment address'); ${resolution}. In the future, this will throw an exception instead of emitting a WARN.`,
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/signableMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class SignableMessage {
this.signature = Buffer.from([]);
this.version = 1;
this.signer = "ErdJS";
this.address = new Address();
this.address = Address.empty();

Object.assign(this, init);
}
Expand Down
4 changes: 2 additions & 2 deletions src/smartcontracts/interaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ export class Interaction {
private gasLimit: IGasLimit = 0;
private gasPrice: IGasPrice | undefined = undefined;
private chainID: IChainID = "";
private querent: IAddress = new Address();
private querent: IAddress = Address.empty();
private explicitReceiver?: IAddress;
private sender: IAddress = new Address();
private sender: IAddress = Address.empty();

private isWithSingleESDTTransfer: boolean = false;
private isWithSingleESDTNFTTransfer: boolean = false;
Expand Down
2 changes: 1 addition & 1 deletion src/smartcontracts/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class Query {
args?: TypedValue[],
value?: ITransactionValue
}) {
this.caller = obj.caller || new Address();
this.caller = obj.caller || Address.empty();
this.address = obj.address;
this.func = obj.func;
this.args = obj.args || [];
Expand Down
4 changes: 2 additions & 2 deletions src/smartcontracts/resultsParser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ describe("test smart contract results parser", () => {
it("should parse contract outcome, on signal error", async () => {
let transaction = new TransactionOnNetwork({
logs: new TransactionLogs({
address: new Address(),
address: Address.empty(),
events: [
new TransactionEvent({
identifier: "signalError",
Expand All @@ -222,7 +222,7 @@ describe("test smart contract results parser", () => {
it("should parse contract outcome, on too much gas warning", async () => {
let transaction = new TransactionOnNetwork({
logs: new TransactionLogs({
address: new Address(),
address: Address.empty(),
events: [
new TransactionEvent({
identifier: "writeLog",
Expand Down
4 changes: 2 additions & 2 deletions src/smartcontracts/smartContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ interface IAbi {
* An abstraction for deploying and interacting with Smart Contracts.
*/
export class SmartContract implements ISmartContract {
private address: IAddress = new Address();
private address: IAddress = Address.empty();
private abi?: IAbi;

/**
Expand All @@ -53,7 +53,7 @@ export class SmartContract implements ISmartContract {
* Create a SmartContract object by providing its address on the Network.
*/
constructor(options: { address?: IAddress, abi?: IAbi } = {}) {
this.address = options.address || new Address();
this.address = options.address || Address.empty();
this.abi = options.abi;

if (this.abi) {
Expand Down
9 changes: 6 additions & 3 deletions src/smartcontracts/transactionPayloadBuilders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import { TypedValue } from "./typesystem";

export const WasmVirtualMachine = "0500";

/**
* A builder for {@link TransactionPayload} objects, to be used for Smart Contract deployment transactions.
*/
/**
* @deprecated Use {@link SmartContractTransactionsFactory} instead.
*
* A builder for {@link TransactionPayload} objects, to be used for Smart Contract deployment transactions.
*/
export class ContractDeployPayloadBuilder {
private code: ICode | null = null;
Expand Down Expand Up @@ -65,6 +64,8 @@ export class ContractDeployPayloadBuilder {
}

/**
* @deprecated Use {@link SmartContractTransactionsFactory} instead.
*
* A builder for {@link TransactionPayload} objects, to be used for Smart Contract upgrade transactions.
*/
export class ContractUpgradePayloadBuilder {
Expand Down Expand Up @@ -120,6 +121,8 @@ export class ContractUpgradePayloadBuilder {
}

/**
* @deprecated Use {@link SmartContractTransactionsFactory} instead.
*
* A builder for {@link TransactionPayload} objects, to be used for Smart Contract execution transactions.
*/
export class ContractCallPayloadBuilder {
Expand Down

0 comments on commit eca0221

Please sign in to comment.