Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
875 changes: 456 additions & 419 deletions src/stdlib/stdlib.ts

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions src/stdlib/stdlib/std/internal/address.tact
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,11 @@ inline fun contractBasechainAddress(s: StateInit): BasechainAddress {
return newBasechainAddress(hash);
}

inline fun contractShardBasechainAddress(s: StateInit): BasechainAddress {
let hash = beginCell().storeShardedStateInit(s).endCell().hash();
return newBasechainAddress(hash);
}

/// Extension function for the `Builder` type. Available since Tact 1.6.0.
///
/// Stores the basechain address in the copy of the Builder and returns that copy.
Expand Down Expand Up @@ -440,3 +445,19 @@ asm(errorCode workchain address) fun forceWorkchain(address: Address, workchain:
CMP
THROWANYIF
}

extends inline fun changeShard(self: Address, shard: Int): Address {
let sl: Slice = self.asSlice();

return beginCell().storeUint(sl.loadUint(11), 11).storeUint(changeShard(sl.loadUint(256), shard), 256).asSlice().loadAddress();
}

extends inline fun getShard(self: Address): Int {
let sl = self.asSlice();
sl.skipBits(11); // addr_std$10, anycast: false, workchain: int8
return sl.loadUint(prefixLength);
}

inline extends fun hasSameShard(self: Address, b: Address): Bool {
return self.getShard() == b.getShard();
}
15 changes: 15 additions & 0 deletions src/stdlib/stdlib/std/internal/cells.tact
Original file line number Diff line number Diff line change
Expand Up @@ -1514,3 +1514,18 @@ asm extends fun computeDataSize(self: Slice, maxCells: Int): DataSize { SDATASIZ
/// See: https://docs.tact-lang.org/ref/core-cells#celldepth
///
asm extends fun depth(self: Cell?): Int { CDEPTH }

extends inline fun storeShardedStateInit(self: Builder, init: StateInit): Builder {
return self
.storeUint(32 + prefixLength, 6) // fixed_prefix_length: true, prefixLength: uint5
.storeUint(6, 4) // special: false, code: true, data: true, library: false
.storeRef(init.code)
.storeRef(init.data);
}

extends inline fun storeStateInit(self: Builder, init: StateInit): Builder {
return self
.storeUint(3, 5) // fixed_prefix_length: false, special: false, code: true, data: true, library: false
.storeRef(init.code)
.storeRef(init.data);
}
6 changes: 6 additions & 0 deletions src/stdlib/stdlib/std/internal/contract.tact
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ inline extends fun hasSameBasechainAddress(self: StateInit, address: Address): B
return baseAddress.hash!! == addressHash;
}

inline extends fun hasSameBasechainAddressWithoutShard(self: StateInit, address: Address): Bool {
let addressHash = parseStdAddress(address.asSlice()).address;
let baseAddress = contractShardBasechainAddress(self);
return extractLowBits(baseAddress.hash!!, 256 - prefixLength) == extractLowBits(addressHash, 256 - prefixLength);
}

/// Global function.
///
/// Computes smart contract's `Address` in the workchain ID 0 (basechain) using the `StateInit` `s` of the contract. Alias to `contractAddressExt(0, s.code, s.data)`.
Expand Down
8 changes: 8 additions & 0 deletions src/stdlib/stdlib/std/internal/math.tact
Original file line number Diff line number Diff line change
Expand Up @@ -527,3 +527,11 @@ fun sqrt(num: Int): Int {

return x;
}

asm fun extractLowBits(value: Int, count: Int): Int {
MODPOW2
}

inline fun changeShard(hash: Int, shard: Int): Int {
return extractLowBits(hash, 256 - prefixLength) | (shard << (256 - prefixLength));
}
50 changes: 50 additions & 0 deletions src/stdlib/stdlib/std/internal/send.tact
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const prefixLength: Int = 8;
/// Ordinary message (default).
///
/// This constant is available since Tact 1.6.0.
Expand Down Expand Up @@ -625,3 +626,52 @@ asm fun acceptMessage() { ACCEPT }
/// See: https://docs.tact-lang.org/ref/core-contextstate#commit
///
asm fun commit() { COMMIT }

struct ShardDeployParameters {
deployParameters: DeployParameters;

/// The shard number to deploy the contract to.
shard: Int as uint8;
}

extends inline fun toShard(self: DeployParameters, shard: Int): ShardDeployParameters {
return ShardDeployParameters {
shard,
deployParameters: self,
};
}

extends inline fun send(self: ShardDeployParameters) {
let newStateInit = beginCell().storeShardedStateInit(self.deployParameters.init).endCell();
let msg = beginCell()
.storeUint(1, 2) // store tag = $0 and ihr_disabled = true
.storeBool(self.deployParameters.bounce)
.storeUint(1 << 10, 14) // store bounced = false and src = addr_none, addr_std$10, anycast: false, workchain = 0 (int8)
.storeUint(changeShard(newStateInit.hash(), self.shard), 256) // addrHash
.storeCoins(self.deployParameters.value)
.storeUint(2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1) // 1 + 4 + 4 + 64 + 32, stateInit: true, inRef: false
.storeRef(newStateInit)
.storeMaybeRef(self.deployParameters.body)
.endCell();

sendRawMessage(msg, self.deployParameters.mode);
}

struct ShardMessageParameters {
messageParameters: MessageParameters;

/// The shard number to deploy the contract to.
shard: Int as uint8;
}

extends inline fun toShard(self: MessageParameters, shard: Int): ShardMessageParameters {
return ShardMessageParameters {
shard,
messageParameters: self,
};
}

extends inline fun send(self: ShardMessageParameters) {
self.messageParameters.to = self.messageParameters.to.changeShard(self.shard);
message(self.messageParameters);
}
Loading