Skip to content

Commit

Permalink
update checklist, more info about promise return
Browse files Browse the repository at this point in the history
  • Loading branch information
PolyProgrammist committed Nov 21, 2024
1 parent 40b7f82 commit 323551a
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
26 changes: 25 additions & 1 deletion docs/2.build/2.smart-contracts/anatomy/crosscontract.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,34 @@ You can attach an unused GAS weight by specifying the `.with_unused_gas_weight()
</TabItem>
</Tabs>

:::info
:::caution

If a function returns a promise, then it will delegate the return value and status of transaction execution, but if you return a value or nothing, then the `Promise` result will not influence the transaction status



Unless there is a very good reason not to, all the cross-contract calling functions should return the Promise as the result of its execution, otherwise, the cross-contract calls won't affect the result of the contract execution.

For example:
<Tabs>
<TabItem value="rs" label="🦀 Rust">

```rust
fn destroy(&mut self) {
Promise::...; // notice the `;` here and the empty return value in the function signature
}
fn destroy(&mut self) -> Promise {
Promise::... // notice there is no `;` here and the return value in the function signature Promise
}
```

</TabItem>
</Tabs>

The difference between the two is that the first will schedule the cross-contract call, but its return value will be ignored (even if the call fails, the result of the `destroy` function will be OK), and transaction return value may even be returned earlier than all the in-flight cross-contract calls complete since they do not affect the execution result.

Without linking the cross-contract call with the result of the `destroy` function, it may start removing itself earlier than the cross-contract call is finished and if it fails, it's state will become unreachable.

:::

:::caution
Expand Down
4 changes: 2 additions & 2 deletions docs/2.build/2.smart-contracts/anatomy/serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,15 @@ When returning the result, the contract will automatically encode the object `B{
into its JSON serialized value: `"{\"success\":true, \"other_number\":0}"` and return this
string.

:::caution JSON Limitations
### JSON Limitations
:::caution
Since JSON is limited to `52 bytes` numbers, you cannot use `u64`/`u128` as input
or output. JSON simply cannot serialize them. Instead, you must use `Strings`.

The `NEAR SDK RS` currently implements the `near_sdk::json_types::{U64, I64, U128, I128}`
that you can use for input / output of data.
:::


---

## Borsh: State Serialization
Expand Down
8 changes: 8 additions & 0 deletions docs/2.build/2.smart-contracts/security/checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,11 @@ Check our [security articles](./welcome.md) to understand how to improve the sec
12. Callbacks are free of `panic!`
13. All the callbacks are given enough GAS to execute entirely
14. The contract is not left in an exploitable state between a cross-contract call and its callback

## Cross-contract calls
15. Cross-contract calling functions [should](../anatomy/crosscontract#creating-a-cross-contract-call) return the Promise as the result of its execution

## Types
16. Use `near_sdk::json_types::{U64, I64, U128, I128}` to avoid deserialization [problems](../anatomy/serialization#json-limitations) with `u64`, etc.
17. Use built in types like `AccountId`, `BlockHeight`, `NearToken` and other types from [near-sdk](https://docs.rs/near-sdk/latest/near_sdk/)
18. When dealing with balances, consider using `checked_mul`, `checked_sub`, etc

0 comments on commit 323551a

Please sign in to comment.