Giter Site home page Giter Site logo

concordium / concordium-rust-smart-contracts Goto Github PK

View Code? Open in Web Editor NEW
58.0 7.0 36.0 4.53 MB

Libraries and tools for writing and testing smart contracts on Concordium

Home Page: https://docs.rs/concordium-std/latest/concordium_std/

License: Mozilla Public License 2.0

Rust 100.00%

concordium-rust-smart-contracts's Introduction

Standard library for writing smart contracts for the Concordium blockchain

Contributor Covenant

This repository consists of libraries for writing and testing smart contracts for the Concordium blockchain in the Rust programming language. It also contains some sample smart contracts. The core library is concordium-std, and the testing library is concordium-smart-contract-testing.

The core library provides procedural macros to reduce the amount of boilerplate the user needs to write, while the concordium-std library exposes a high-level API that smart contract writers can use when writing contracts, alleviating them from the need to deal with low-level details of how the interaction with the chain works.

Versions

  • concordium-std prior to version 3 supported version 0 contracts
  • concordium-std version 3 only supports building version 1 contracts

cargo-concordium version dependencies

  • concordium-std version 4 only works with cargo-concordium version 2.1+.
  • concordium-std version 5 only works with cargo-concordium version 2.4+.

Examples

The examples directory contains some smart contracts that are used to test the standard library.

These contracts are not meant for production, they are used to illustrate how to use the standard library and the tooling Concordium provides. There is no claim that the logic of the contract is reasonable, or safe.

Do not use these contracts as-is for anything other then experimenting.

Submodules

The repository has concordium-rust-sdk as a submodule, and testing and builds are set-up to use the submodule version. When changes are made in concordium-rust-sdk they should be propagated to this repository.

Contributing

Contributor Covenant

This repository's CI automatically checks formatting and common problems in rust. Changes to any of the packages must be such that

  • cargo clippy --all produces no warnings
  • rustfmt makes no changes.

Everything in this repository should build with rust version 1.67 however the fmt tool must be from a nightly release since some of the configuration options are not stable. One way to run the fmt tool is

cargo +nightly-2023-04-01 fmt

(the exact version used by the CI can be found in .github/workflows/linter.yml file). You will need to have a recent enough nightly version installed, which can be done via

rustup toolchain install nightly-2023-04-01

or similar, using the rustup tool. See the documentation of the tool for more details.

In order to contribute you should make a pull request and ask at least two people familiar with the code to do a review.

concordium-rust-smart-contracts's People

Contributors

abizjak avatar amaurremi avatar anfid avatar annenkov avatar bargsteen avatar bogacyigitbasi avatar chrmatt avatar doben avatar eb-concordium avatar jakobbotsch avatar lassemoldrup avatar limemloh avatar lottekh avatar milkywaypirate avatar nossicasystems avatar parv0888 avatar rasmus-kirk avatar rimbi avatar simonkamp avatar soerenbf avatar target-san avatar td202 avatar tschudid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

concordium-rust-smart-contracts's Issues

Add logos to the published documentation.

Task description

Add documentation metadata to the published crates, in particular we should set the logo and issue tracker urls, see https://doc.rust-lang.org/rustdoc/the-doc-attribute.html#at-the-crate-level

Sub-tasks

  • Add favicon to std, std-derive, contracts-common
  • Add logo to std, std-derive, contracts-common
  • Add issue tracker urls for all of those

The logo and icon are attached (they don't have a background and the foreground is a white logo, so they might appear as blanks below)
image
image

Cargo concordium should output NRG cost in addition to just the interpreter energy.

Task description

When executing contracts with cargo concordium it currently outputs "interpreter energy", which is not the same as NRG used by the chain. Additionally, it only accounts for execution costs, not for other costs associated with contract execution.

The formula for calculating cost of smart contract invocation has contract specific cost

The cost of a smart contract update is

(MS+ SE) / 10 + IE + B * SS + 300

where

  • MS is size of the smart contract module in bytes
  • SE is the size of the contract state
  • IE is the execution cost of the contract in NRG. The only practical way to estimate this is to execute it and observe it, e.g., with cargo-concordium.
  • B is 1 if invocation succeeds, and 0 otherwise
  • SS is the size of the new contract state.

Additionally there is the general contract cost based on the number of signatures and size. This should probably not be part of cargo-concordium, but it should communicate this.

The first step should be designing a good interface for the output that communicates clearly.

Have HasParameter implement Seek

Description

Currently, HasParameter does not implement the Seek trait, which is useful for some optimizations of deserializing.

The implementation should behave very similar to the one for ContractState, and it might be possible to reuse this in a shared type.

Contract fallback methods: revise #receive macros and expose entrypoint name

Task description

Contract fallback methods for V1 contracts are defined as a method with an empty entrypoint name.

To make this a bit safer we want to

  • in the #receive macro ensure that name is always non-empty.
  • add a "default" option to the receive macro, so #[receive(contract = "fib", fallback)] which generates an export with name "fib.", denoting the fallback method.

Additionally, to make these useful, we need to add a method to the receive context to get the actual name of the entrypoint that was invoked.

Consider exporting the entire collections from concordium-std

Task description

Currently we export some datatypes (e.g., BTreeMap) but not some auxiliaries. It probably makes sense that we export the entire module as is done by the std crate. In case of BTreeMap the Entry api is of particular interest.

Investigate whether to add a fixed-point type

Task description

It might make sense to have a type to represent fixed-point fractional values and support calculations on it as part of concordium-std.

The design needs to be well thought-out to satisfy at least the following

  • efficient at runtime. Fixed point computation are for the most part just computation with integers so we should not be needlessly wasteful.
  • type safety
  • correct and well-documented rounding behaviour. Failure should be explicit.

Sub-tasks

  • Investigate the design space and make a proposal.
  • Implement the API and test.
  • Analyze performance, code size of generated code.

Expose the type of parameters in init and receive signatures

Task description

The parameter to smart contracts is accessible via the context as context.parameter_cursor(). This is a cursor that implements Read and HasParameter, so parameters can either be read lazily, or deserialized in one go, for example with Get::get.

This is flexible and as efficient as it can be in the general case.

However in the cases where the parameter is used it would be convenient to add better support for just passing it as a parameter.

The proposal is to extend the init and receive macros with a parameter attribute. This attribute already exists and is used to add types to the schema. It currently must always be of the form parameter = "Foo".

I propose that we add additional options to the parameter.

  • if parameter alone is present among the attributes then the meaning is to expect the init or receive method to have an additional parameter. In relation to payable and enable_logger it should fit after payable and before enable_logger. Amounts are like parameters, so this would make sense. In this form the parameter has no effect on the schema.
  • if parameter(auto) is present then the meaning is as in the previous item but additionally it adds the parameter type to the schema. It automatically deduces the type from the parameter list of the function.
  • if parameter = "Foo" is present the meaning is as it is currently.

Subtasks

  • Finalize the design.
  • Implement the changes.
  • Modify existing examples or add new ones. Making sure to observe generated code, size and cost.
  • Update smart contract documentation to reflect the new parameter. This means library documentation as well as developer documentation.

Only allow valid attributes for `#[init]` and `#[receive]`

Description
Currently, the procedural macros #[init] and #[receive] takes a number of attributes, (contract, name, parameter ...), but there are no check for the user to only provide defined attributes.

Say, a user mistypes parameter, since this won't produce any compile time error, the user will have to notice the missing function in the schema.

Synchronous contract calls: concordium-std support

Task description

Synchronous contract calls change the format of the contract entrypoints fairly significantly. These changes must be reflected in concordium-std to enable painless writing of smart contracts.

The next version of concordium-std will not support V0 contracts anymore, only V1.

Some of the similar changes to contracts are going to be needed for the state implemenation. However the changes should be done in two stages to make them more manageable.

Sub-tasks

  • Wrap the new host API into ergonomic high-level wrappers (e.g., invoke_contract, transfer, ...)
  • Introduce a version 2 of the schema that removes support for the state from the schema, but adds support for return values.
  • Revise procedural macros (i.e., the init and receive macros, as well as the schema macro) for the new format of contracts.
  • Update testing infrastructure to allow testing of new contracts.

Make v1 mock functions the default

Description

Currently, there are three new functions for MockFn in the testing infrastructure.
new which can mock both v0 and v1 functions.
new_V1 which only mocks v1 (always has a return value on success)
new_v0 which only mocks v0 (never has a return value)

I propose that we make v1 contracts the default, so we have
new which only mocks v1 contracts.
new_v0 which only mocks v0 contracts.

New contract state: concordium-std support

Task description

This is part of the new contract state feature, see also Concordium/concordium-node#237

Since the state will look very different in V1 contracts we will need to significantly revise the support for using it. The key features that need to be provided by concordium-std are

  • efficient mappings from small objects (e.g., account addresses, token IDs) to (potentially) more complex objects
  • efficient sets of small objects (e.g., account addresses, token IDs)
  • easy to use state with multiple fields, e.g., a Rust struct as the state of a smart contract
  • nested maps and sets should be possible and painless

Some of this will require writing new procedural macros to generate code for users as much as possible, based on their annotations.

As usual, this needs to be provided in two variants, one for use on the chain, and one for unit testing. The latter will involve essentially implementing the same kind of backing radix trie implementation as is used by the node, except the implementation does not have to deal with persistence.

Proposed API for the new contract state

/// Lookup an entry with the given key. The return value is either
/// u64::MAX if the entry at the given key does not exist, or else
/// the first bit of the result is 0, and the remaining bits
/// are an entry identifier that may be used in subsequent calls.
fn state_lookup_entry(key_start: *const u8, key_length: u32) -> u64;

/// Create an empty entry with the given key. The return value is either u64::MAX if
/// creating the entry failed because of an iterator lock on the part of the
/// tree, or else the first bit is 0, and the remaining bits are an entry identifier
/// that maybe used in subsequent calls.
fn state_create_entry(key_start: *const u8, key_length: u32) -> u64;

/// Delete the entry. Returns one of
/// - 0 if the part of the tree this entry was in is locked
/// - 1 if the entry did not exist
/// - 2 if the entry was deleted as a result of this call.
fn state_delete_entry(entry: u64) -> u32;

/// Delete a prefix in the tree, that is, delete all parts of the tree that have
/// the given key as prefix. Returns
/// - 0 if the tree was locked and thus deletion failed.
/// - 1 if the tree **was not locked**, but the key points to an empty part of the tree
/// - 2 if a part of the tree was successfully deleted
fn state_delete_prefix(key_start: *const u8, key_length: u32) -> u32;

/// Construct an iterator over a part of the tree. This **locks the part of the
/// tree that has the given prefix**. Locking means that no deletions or
/// insertions of entries may occur in that subtree.
/// Returns
/// - all 1 bits if too many iterators already exist with this key
/// - all but second bit set to 1 if there is no value in the state with the given key
/// - otherwise the first bit is 0, and the remaining bits are the iterator identifier
/// that may be used in subsequent calls to advance it, or to get its key.
fn state_iterate_prefix(prefix_start: *const u8, prefix_length: u32) -> u64;

/// Return the next entry along the iterator, and advance the iterator.
/// The return value is
/// - u64::MAX if the iterator does not exist (it was deleted, or the ID is invalid)
/// - all but the second bit set to 1 if no more entries are left, the iterator
/// is exhausted. All further calls will yield the same until the iterator is
/// deleted.
/// - otherwise the first bit is 0, and the remaining bits encode an entry
///   identifier that can be passed to any of the entry methods.
fn state_iterator_next(iterator: u64) -> u64;

/// Delete the iterator, unlocking the subtree. Returns
/// - u64::MAX if the iterator does not exist.
/// - 0 if the iterator was already deleted
/// - 1 if the iterator was successfully deleted as a result of this call.
fn state_iterator_delete(iterator: u64) -> u32;

/// Get the length of the key that the iterator is currently pointing at.
/// Returns
/// - u32::MAX if the iterator does not exist
/// - otherwise the length of the key in bytes.
fn state_iterator_key_size(iterator: u64) -> u32;

/// Read a section of the key the iterator is currently pointing at. Returns either
/// - u32::MAX if the iterator has already been deleted
/// - the amount of data that was copied. This will never be more than the supplied length.
fn state_iterator_key_read(iterator: u64, start: *mut u8, length: u32, offset: u32) -> u32;

// Operations on the entry.

/// Read a part of the entry. The arguments are
/// entry ... entry id returned by state_iterator_next or state_create_entry
/// start ... where to write in Wasm memory
/// length ... length of the data to read
/// offset ... where to start reading in the entry
/// The return value is
/// - u32::MAX if the entry does not exist (has been invalidated, or never
/// existed). In this case no data is written.
/// - amount of data that was read. This is never more than length.
fn state_entry_read(entry: u64, start: *mut u8, length: u32, offset: u32) -> u32;

/// Write a part of the entry. The arguments are
/// entry ... entry id returned by state_iterator_next or state_create_entry
/// start ... where to read from Wasm memory
/// length ... length of the data to read
/// offset ... where to start writing in the entry
/// The return value is
/// - u32::MAX if the entry does not exist (has been invalidated, or never
/// existed). In this case no data is written.
/// - amount of data that was written. This is never more than length.
fn state_entry_write(entry: u64, start: *const u8, length: u32, offset: u32) -> u32;

/// Return the current size of the entry in bytes.
/// The return value is either
/// - u32::MAX if the entry does not exist (has been invalidated, or never
/// existed). In this case no data is written.
/// - or the size of the entry.
fn state_entry_size(entry: u64) -> u32;

/// Resize the entry to the given size. Returns
/// - u32::MAX if the entry has already been invalidated
/// - 0 if the attempt was unsuccessful because new_size exceeds maximum entry size
/// - 1 if the entry was successfully resized.
fn state_entry_resize(entry: u64, new_size: u32) -> u32;

Sub-tasks

  • Expose the new host functions as a high-level interface (as much as possible).
  • Provide/revise the procedural macros that generate low-level functions from high-level entrypoints.
  • Update the testing infrastructure for new state.
  • Update existing, and provide new examples of smart contracts using the new API.
  • Revise documentation as needed.

Add helpers to check which mock functions were invoked

Task description

In the test infrastructure, the TestHost has a number of helper methods for verifying the transfers that occurred.
It should have the same options for mock functions.
A bit of experimentation will likely be required to figure out what the helper methods should do and return.

The simplest option is something like:
TestHost::mocks_invoked(&self) -> Vec<(ContractAddress, EntrypointName)>

But there could also be method that shows the parameter, amount, etc. used for each invocation of a mock function.

Sub-tasks

  • Figure out which helper methods are needed
  • Track the data necessary to said methods (for example by adding a vector of invoked mock functions to TestHost)
  • Implement the helper methods

Test host for multiple contracts

Currently the TestHost have functionality to mock an entrypoint.

It would be nice to extend this with functionality to setup another contract with state for an entrypoint, for applications which have multiple smart contracts, such as an NFT contract and a listing contract.

Add more introspection capabilities to TestHost

Task description

Add more tracing/introspection capabilities to TestHost. Currently you can observe which transfers occurred and in what order.

At least the following should be added

Sub-tasks

  • Which contracts, in what order, and with what parameters were invoked, and what were the responses.

Contract parameter parsing error!

Description
image
image
It can be seen that my parameter is a structure, and the parsing in the contract is an address, but I don't understand why the parsing can be successful, it feels like the first 32 bytes taken directly can be converted into an address, then the following elements are directly discarded , which is unreasonable.

Expected Result
It should return an error in time or fail to execute!

Versions

  • Software Version
    concordium-std = {version = "2.0.0", default-features = false}

tx.origin/invoker variable should not be used for authentication in smart contracts

Description
Solidity uses the variable tx.origin (the equivalent variable is invoker on the Concordium chain) to denote the address that initiated a tx.

Smart contract best practice guides advise NOT to use tx.origin/invoker for authentication/authorization in smart contracts because phishing attacks are possible with such a setup.
Additional reading here and here

Suggested changes to following line:
claim_eq!(ctx.owner(), ctx.sender());

Alternative suggestion:
I know that these smart contracts are not meant for production but I suspect new smart contract developers to kick start their projects based on these examples nonetheless. If we want to keep the invoker variable at this line then I would at least add a warning comment above it so people are aware of it.

Please remove the label "question" if it is ok that I work on it or close the issue to reject the suggested changes.

Describe which parts of Rust should not be used in smart contracts

We have a brief mention of the fact you can’t use floats, but we do not have any more details on the limitations on resources, and more importantly, limitations on input/output functionality, and lack of threads.

And the fact that the platform is a 32-bit one.

  • You cannot use any IO functionality
  • Modules can be at most 65k
  • No concurrency.
  • ...?

Wrapped CCD Token (WCCD)

We currently don't have a specification or an implementation for a wrapped CCD token. (Tacans)

Stories:

  • (1) Provide WCCD Specification
  • (2) Implement Smart Contract
  • (3) Additional features to operate the smart contract:

[ ] Adding an admin address that is authorized to do maintenance tasks in the smart contract. #128

[ ] Adding the capability to pause contract by the admin address. #128

[ ] Adding pattern to upgrade the implementation contract. #128

  • (4) Update documentation on the website with an example wrapper token

Provide bigger examples of using low-level contract interface.

Task description

The new contract state provides high and low-level API (as the old state did).

We have many examples using the high-level state, but few using the low-level state.
Based on experience from users some do use the low-level interface for efficiency, so we should provide examples of that.

Improve error reporting when `mutable` is used incorrectly

Task description

Currently if the user does not use the mutable attribute on a receive entrypoint, but has &mut impl HasHost<...> as the type of the host the error message is quite bad and talks about internals that are not exposed to the user.

It would be good to improve on this. In general we cannot do much since users can define aliases for &mut impl HasHost<...> or use more specific types there. However probably in the most common case we could improve the message.

If the user writes &mut _ at the argument position and they have not used mutable then that is definitely an error and we can produce a nice error message.

Move serialization macros out of concordium-std-derive into its own crate

Task description

Currently it is not possible to use serialization derivation macros in off-chain code since it is part of concordium-std-derive, which is not meant to be used by off-chain code (it essentially depends on concordium-std and its imports).

We should split out the serialization macros into its own crate and change the imports to use concordium-contracts-common instead.
This will allow using them from off-chain code. This crate should live in concordium-contracts-common repository.

Sub-tasks

  • split out the serialization macros
  • re-export appropriately from concordium-std so there is no API change there.

Zero copy serialization for parts of smart contracts

Some types and values (e.g., account addresses) are likely to benefit from a more efficient serialization scheme, both in code space and execution time.

This will also allow removing the reliance on alloc.

We should consider having a more precise interface to serialization that is harder to use, but allows for zero-copy deserialization for parts where it matters.

Improvements should be accompanied by data and benchmarks.

Returning funds immediately when outbidded by another bid (this will prevent having to use loops that can run out of gas)

Description
Loops can run out of gas in smart contracts, therefore they are used very rarely in smart contracts (only when we can ensure that we are in control of the size of the object that the loop is iterating through).

Example when loops can be used safely:
If the owner of a smart contract adds addresses to a list, then it is perfectly fine to iterate via a for loop over this list since we can assume that the owner of the smart contract is a smart contract developer and knowledgable enough to not insert too many addresses in the list.

Example when loops should be avoided:
If a general user calls our smart contract and this action causes an e.g. address to be inserted in a list then we don't have any control of the size of the list anymore. If our smart contract protocol becomes super popular the list can grow significantly. In addition, competitor protocols might on purpose call this function to blow up our list so that any loop that iterates through the list in our smart contract is now reverting (parts of our protocol become inexecutable).

Suggestion for the auction example:
Since the payout function of the auction example iterates via a for loop over an object that was grown in size by user actions, we should safeguard that the size of the object does not grow too large. This is to prevent the smart contract to be unable to pay out its rewards (causing the funds to be stuck in the smart contract).

  1. STEP: Adding a variable MAX_PARTICIPANTS :

    const MAX_PARTICIPANTS: u32 = 100;

  2. STEP: Adding a counter of how many addresses/users/bids already participated in our auction:

    /// Number of bids in the StateMap bids
    number_of_bids: u32

  3. STEP: Checkinging in the bid receive funciton that we are not inserting too many addresses
    ensure!(MAX_PARTICIPANTS >= state.viewable_state.number_of_bids,
    BidError::MaxParticipantsReached);

Please remove the label "question" if it is ok that I work on it or close the issue to reject the suggested changes.

In concordium-std, let user specify enum variant to be used as Default error

A user can now write the following code:

#[derive(Reject)]
enum MyReceiveError {
  MyErrorVariant,
  ...
}

fn receive(...) -> Result<A, MyReceiveError> {
  ...
}

We would like to be able to call bail from receive functions that use custom error types. But for that, we need to provide a Default implementation for errors.

This task is to allow the user to write

#[derive(Reject)]
enum MyReceiveError {
  #[default]
  MyErrorVariant,
  ...
}

which will generate a Default implementation

impl Default for MyReceiveError {
  fn default() -> Self {
    MyReceiveError::MyErrorVariant
  }
}

Non-payable does not have the correct error code assignment

Bug Description

Reserved error codes in concordium-std are meant to have error codes in the range i32::MIN..i32::MIN+100.
In concordium-std-derive we have the "this contract does not accept GTU" error code (when the payable flag is not set) which returns -1.

We should instead have a defined error code for "NotPayable" and assign it a value in the above mentioned range.

Steps to Reproduce

Invoke a contract without the payable flag with non-zero GTU and use the #[init]/#[receive] macros. Observe the error code.

Expected Result

A predefined reserved error code

Actual Result

Return -1

Rethink the Deletable abstraction

Task description

The Deletable trait/abstraction was added to ensure that nested maps/sets would clean up after themselves when elements were removed. However it is not very clean.

In particular we have a

  • blanket implementation of Deletable for anything Serializable
  • specific implementations for StateBox/StateMap/StateSet

This smells and only barely works. The reason it works is that deletable and statebox/statemap/stateset are defined in the same crate and not serializable. If this was not the case then we'd have problems with overlapping instances.

It also makes it a bit magical, and relatively confusing for users, especially if they do not have the relevant traits implemented or derived for their types.

An alternative would be to have a specific wrapper type (analogous to ManuallyDrop or UnsafeCell that would implement Deref and DerefMut and be deletable as soon as the contents was flat. But there might be other options.

The considerations for a choice are

  • good ergonomics when used correctly. No need for extensive boilerplate.
  • as hard to use incorrectly as possible (ideally impossible)
  • when used incorrectly, error messages should be understandable

Make all doctests runnable in concordium-std/std-derive

Task description

Currently doctests (tests that are part of doc-comments) either don't compile or don't run. We'd ideally have them compile and run, so that they can be maintained properly.

Basically cargo test should work.

Cryptographic Primitives for Smart Contracts

In order to make it more cost effective to do some basic cryptographic operations that are needed for certain applications we need to add them as primitives to contracts.

This is a minimal version to be included in Sirius for immediate needs of upcoming use-cases.

These primitives are

  • ed25519 signature checking
  • ecdsa over secp256k1 signature checking (bitcoin/ethereum scheme)
  • sha2-256 hashing
  • sha3-256 hashing
  • keccak-256 hashing (this is almost sha3, but with a padding difference, it is what Ethereum uses in their smart contracts, hence the motivation).

Standardize a way for smart contracts to log memos

Task description

Provide a standard template on how a smart contract should immitate a memo feature when doing transfers to accounts.

The transfer message cannot contain any metadata in addition to the amount. But a contract can omit events. The task is to define the format of events that will serve the same purpose as the memo field of a a transfer with metadata.

  • Define the format.
  • Provide a not-entirely-trivial example of a contract in the examples folder.

Parameter is ambiguous name

Bug Description
When I compiled with the latest version of concordium trust smart contracts, an error occurred. I found that Parameter is a conflicting variable because it is in concordium-std\type.rs and concordium-contract-common\type.rs has a definition.
We're at concordium-std\impl.rs uses a Parameter, which makes the compiler unable to know which parameter we want to use.

Steps to Reproduce

Expected Result

Actual Result

_Compiling concordium-std v2.0.0 (D:\contract2\concordium-rust-smart-contracts-main\concordium-rust-smart-contracts-main\concordium-std)

error[E0659]: Parameter is ambiguous (glob import vs glob import in the same module)
--> D:\contract2\concordium-rust-smart-contracts-main\concordium-rust-smart-contracts-main\concordium-std\src\impls.rs:274:15
|
274 | impl Read for Parameter {
| ^^^^^^^^^ ambiguous name
|
note: Parameter could refer to the struct imported here
--> D:\contract2\concordium-rust-smart-contracts-main\concordium-rust-smart-contracts-main\concordium-std\src\impls.rs:12:5
|
12 | use concordium_contracts_common::;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: consider adding an explicit import of Parameter to disambiguate
note: Parameter could also refer to the struct imported here
--> D:\contract2\concordium-rust-smart-contracts-main\concordium-rust-smart-contracts-main\concordium-std\src\impls.rs:8:5
|
8 | types::
,
| ^^^^^^^^
= help: consider adding an explicit import of Parameter to disambiguate

error[E0659]: Parameter is ambiguous (glob import vs glob import in the same module)
--> D:\contract2\concordium-rust-smart-contracts-main\concordium-rust-smart-contracts-main\concordium-std\src\impls.rs:289:23
|
289 | impl HasParameter for Parameter {
| ^^^^^^^^^ ambiguous name
|
note: Parameter could refer to the struct imported here
--> D:\contract2\concordium-rust-smart-contracts-main\concordium-rust-smart-contracts-main\concordium-std\src\impls.rs:12:5
|
12 | use concordium_contracts_common::;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: consider adding an explicit import of Parameter to disambiguate
note: Parameter could also refer to the struct imported here
--> D:\contract2\concordium-rust-smart-contracts-main\concordium-rust-smart-contracts-main\concordium-std\src\impls.rs:8:5
|
8 | types::
,
| ^^^^^^^^
= help: consider adding an explicit import of Parameter to disambiguate_

Versions

  • Software Version
    concordium-std= “2.0.0”
    concordium-contracts-common = “2.0”

  • OS
    windows

  • Browser

  • Mobile device, if applicable

Improve library documentation of error codes

Task description

The error codes returned from smart contracts are fairly poorly documented. There is no overview of them in the library documentation, and we do not list in one place the pre-defined error codes for things like the NewReceiveNameError.

We need to make this more easily discoverable in the output of cargo doc

Documentation of serialization needs improvement

Task description

The library documentation of serialization is not entirely comprehensive.

In https://docs.rs/concordium-std/0.5.0/concordium_std/derive.Serial.html we could be more structured and clear.

  • link to the actual trait

In https://docs.rs/concordium-std/0.5.0/concordium_std/trait.Serial.html we do not provide an overview of the serialization, and we are not explicit about serialization of many types, in particular integral types, timestamp, amount, ...

  • each type where we write a manual instance should have clear documentation on how it is serialized. If the instance is derived in the core library it must also be documented what the format is.

Explain account-balance logic in receive functions

In the developer documentation, clarify how the GTU that is passed into a receive function relates to the account balance. Specifically, explain that the receive-context balance excludes the GTU passed into the receive function, but that the function will still have enough GTU to execute actions that require the sum of the context balance + passed in amount.

Research variable length encoding of CIS-2 token amounts

Tokens standards on Ethereum uses an unsigned 256 integer to represent token amounts, which might cause issues with CIS2's choice of using u64 when application across bridges.

We should reseach the implications of using a variable length encoding such as LEB128 for token amounts in order to support large token amounts while still keeping the option to use a smaller type for the smart contract implementation.

We do this by implementing LEB128 for serializing token amounts in one of the examples and observe the difference in energy cost for interaction and smart contract module size.

Improve getting started guide

It would be nice to have a step-by-step tutorial covering everything from installing the tools, to compiling, deploying on chain, and invoking a contract. Maybe even something simpler than the Piggy Bank. At the moment, one needs to go back and forth quite a bit and there is no minimal introduction.

Better support for return values for failures.

Task description

With the introduction of synchronous calls in #71 contracts can return values now, even if they fail due to a logic error.
However the support for this in concordium-std is limited. We only support it via manually implementing Into<Reject> for your chosen error type, and to implement this one needs to produce a Vec. This is less ergonomic than our other support, where we do serialization behind the scenes.

This is related to #71 . It is not blocking for it, but it will likely need some API changes in the library, so it would be good to have it done before release.

Address clippy warnings about using `panic!` without a string literal.

Task description

In some cases for the test infrastructure we use the panic! macro in no_std mode with a message that is not a string literal, but it is a string formatted using format. This causes clippy to complain and might become an error in the future. We should try to fix this.

Improve actions documentation in the library.

Task description

The library documentation (the one produced by cargo doc) is pretty poor when it comes to how actions work.
We need to document this better, and explain on examples so that people can be comfortable using actions, and understand the caveats that come with them.

Make non-reentrant mock functions the default

Description

Currently, MockFn::new[_v0, _v1] gets the &mut Amount and &mut State parameters so that you can mock contracts that use reentrancy (contracts that call themselves, either directly or transitively).

I propose that we simplify the API by renaming the MockFn::new[_v0, _v1] methods to *_reentrancy (or similar) and add new some newMockFn::new[_v0, _v1] methods that do not have the &mut Amount and &mut State parameters, thereby making the simpler version the "default".

The new methods should thus be:

  • new-variants will expect a closure of `|Parameter, Amount| -> Result<..>
  • new_reentracy-variants will expect a closure of |Parameter, Amount, &mut Amount, &mut State| -> Result<..>

Add ability to use concordium-std without alloc

Currently concordium-std sets a global allocator and itself depends on the alloc crate.
For advanced uses this is not ideal, and we should support building without alloc, as well as allowing users to use their own allocator as opposed to wee-alloc.

This means another feature and putting all the alloc related things behind it.

Building without alloc will reduce code size and build times, in general, and we should have better support for it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.