Code Monkey home page Code Monkey logo

move's People

Contributors

ankushagarwal avatar bmwill avatar bothra90 avatar davidiw avatar dependabot-preview[bot] avatar dependabot[bot] avatar dimroc avatar emmazzz avatar gregnazario avatar huitseeker avatar joshlind avatar junkil-park avatar lightmark avatar ma2bd avatar meng-xu-cs avatar metajack avatar mimoo avatar msmouse avatar phlip9 avatar rexhoffman avatar runtian-zhou avatar rustielin avatar sausagee avatar sblackshear avatar sunshowers avatar vgao1996 avatar wrwg avatar xli avatar zekun000 avatar zihaoccc 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  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  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

move's Issues

[move package test] panics when cache is hot

Right now if you run move package test inside a package that depends on MoveStdlib and MoveStdlib only, for the first time it'll succeed:

BUILDING MoveStdlib
BUILDING Foo
Running Move unit tests
[ PASS    ] 0x1::A::one_plus_one
[ PASS    ] 0x1::A::should_panic
[ PASS    ] 0x1::A::test_with_arg
Test result: OK. Total tests: 3; passed: 3; failed: 0

However if you run this command for the second time, it complains about not being able to find a source file:

CACHED MoveStdlib
BUILDING Foo
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: No such file or directory './build/MoveStdlib/sources/ASCIITests.move'', language/tools/move-cli/src/package/cli.rs:510:83

[Bug] Struct name identifier in unpack statement does not preserve location in translate AST

πŸ› Bug

Consider the following unpack statement:

let SomeStruct { some_field: value } = s;

In the statement above, the SomeStruct identifier does not have its own identity (e.g., with respect to its location in the source file) but rather is an alias to the struct definition identifier. This will cause problems when trying to build use-def information for identifiers in the source code (e.g., for the purpose of displaying this information in an IDE).

A simple solution is to stick the location information into the Unpack structure, but:

  • a more general solution may exist (e.g., store "full" identifier info (Name) along with the alias to the struct definition)
  • there may be other places where this kind of aliasing causes "use" identifiers to loose their identity

[Design Task] Guidelines and tooling support for Move code portability

Move compatibility in general. There were already some compatibility challenges due to differences in frameworks (e.g., libraries that depend on DiemAccount aren't compatible with ones that depend on StarcoinAccount), and Sui Move's data model that differs from core Move's global storage will throw another wrench in the works. Some incompatibility is to be expected given the nature of Move (a platform-independent language that gives platform designers a lot of flexibility to customize both the Move runtime and libraries for their platform). But of course, we should still strive for as much compatibility as possible and suggest best practices that will help with this.

Some early thoughts on this:

  • Compatibility should be a source/package level concern. Striving for compatibility at the bytecode level across different networks is a much harder task, and it's not clear that it's needed (and thus, I think is a task that we should not attempt). There are packages that can be 100% compatible at the source level, but incompatible at the bytecode level due to hardcoded addresses, address length, and in the future, possibly other factors like varying the serialization format. However, none of these are blockers for source compatibility, at least not in principle.
  • An obvious best practice is to suggest not writing "non-portable" code that depends on address length or serialization format. This is very similar to (e.g.) not writing C code that depends on the pointer size.
  • We can suggest "tiering" modules based on how likely they are to be reusable, and encourage packages to only group modules in the same tier. Otherwise, someone might want to depend on some reusable module in a package, but be blocked by some incompatible (but unused) module in the same package. Some natural tiers that come to mind are:
  1. Modules that only define utility functions and do not define any types (e.g., a Math.move module). They must (transitively) only depend on other tier 1 packages. These are fully generic and can be used by any platform.
  2. Modules that define utility functions and expose utility types (e.g., ASCII::String in the stdlib). They must (transitively) only depend on other tier 1-2 packages. These can be used by any platform in principle, but there's nothing that stops two platforms from (e.g.) defining and reusing type-incompatible versions of UTF8::String. We should try to avoid this by working as a Move community to build canonical libraries of these types.
  3. Same as (2), but also has some native functions. They must (transitively) only depend on other tier 1-3 packages. These can be used by any platform in principle, but some platforms might not want to use the native functions defined by some other platform because native functions can violate the rules of core Move (e.g., by creating addresses from scratch).
  4. Same as (3), but also has entrypoints. Different platforms can (and will) choose different rules for entrypoints that may not be compatible. These must (transitively) only depend on other tier 1-4 packages. These are only reusable across platforms with the same entrypoint structure.
  5. Same as (4), but also uses global storage (e.g., borrow_global, Table). These must (transitively) only depend on other tier 1-5 packages. These are only reusable across platforms with the same entrypoint structure and global storage.
  6. Same as (5), but also uses platform-specific packages/types (e.g. accounts, transactions, time, validator set management, ...). These are not likely to be compatible with other packages. Perhaps over time, we can define source-level "interfaces" for some of these concepts to allow compatibility for similar platforms, but I wouldn't want to rush into this. Some level of incompatibility is always going to be expected here.

I'm not sure whether this tiering system should just be an informal guideline, or also something that we try to enforce programmatically in the package system and/or linters. It's worth noting that packages are not organized according to this tiering system today, although some are close (e.g., there's very little global storage used in the Move stdlib). But the overwhelming tendency is toward monolithic tier 6 packages, which I think we should change.

Once we have reorganized packages using these principles, I think there will be a lot more boxes in your diagram above, but the tiering system will make it easier to figure out where we can/should draw dependency arrows and where we shouldn't.

(copied from original discussion in diem/move#91)

[evm] `npx hardhat test` get affected by previous Move packages in a different git branch

See the error log:

$ npx hardhat test
An unexpected error occurred:

[Error: ENOENT: no such file or directory, stat '/Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC721Mock/Move.toml'] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'stat',
  path: '/Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC721Mock/Move.toml'
}

contracts/ERC721Mock does not exist in this branch. It did in a different branch. However, it complains.

[evm] `npx hardhat compile` does not pass the compile error from the Move compiler

npx hardhat compile
Nothing to compile
Building 10 Move packages...
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Caller
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC20DecimalsMock
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC20Mock
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Event

Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ExternalCall
Error: exiting with Yul generation errors

Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/FortyTwo
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Greeter
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Native
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Revert
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Token
An unexpected error occurred:

Error: Failed to build one or more Move packages
    at SimpleTaskDefinition.action (/Users/jkpark/Work/move/language/evm/hardhat-move/src/index.ts:388:19)
    at Environment._runTaskDefinition (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:219:14)
    at Environment.run (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:131:14)
    at SimpleTaskDefinition.action (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/builtin-tasks/compile.ts:1422:7)
    at Environment._runTaskDefinition (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:219:14)
    at Environment.run (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:131:14)
    at main (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/cli/cli.ts:218:5)

[Feature Request] Enable script function with signer reference

πŸš€ Feature Request

Motivation

As script function can support more flexible parameters, we plan to enable passing signer reference instead of signer in script and script function to reduce redundant code. Ex: developer has to write script function taking signer and a internal version of script function to take &signer so that they can test with internal version of function without worrying about the signer value being "moved". This leads to lot of code duplication and force developer to understand unnecessary language details

However,

First, the ABIgen current still assumes all non-signer args are actually function arguments. while passing &signer, it is treated as true txn arguments passed by users leading to abigen failed.

second, the move viewer also has the same assumption that should be relaxed.

Pitch

Describe the solution you'd like
relax the assumption in abigen so that both signer and non-mutable signer reference are not txn args.

[Feature Request] Keep the finer granular error code for MiscellaneousError

πŸš€ Feature Request

Motivation

Multiple different errors all mapped to MiscellaneousError ex:

  1. https://github.com/areshand/move/blob/0747a72af49e7116ae2b54625668d8536ee086d8/language/move-core/types/src/vm_status.rs#L182
  2. https://github.com/areshand/move/blob/0747a72af49e7116ae2b54625668d8536ee086d8/language/move-core/types/src/vm_status.rs#L187

The impact is user lacks a clear idea of what went wrong when their txn failed. Ex:
when users published modules, both the linker_error and MODULE_ADDRESS_DOES_NOT_MATCH_SENDER are mapped to this MiscellaneousError, which doesn't help user to understand what went wrong.

Pitch

Describe the solution you'd like
Keep the finer granular status code when returning the MiscellaneousError to provide more detailed error message to the users

[evm] Compile error "error: Invalid value "ethereum" for '--arch <ARCHITECTURE>'

$ npx hardhat compile
Nothing to compile
Building 14 Move packages...

Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Native
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help


Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Greeter
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help


Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/FortyTwo
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help


Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ExternalCall
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help


Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Event
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help


Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC721Tradable
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help


Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC721Mock
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help


Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC20Mock
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help


Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC20DecimalsMock
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help


Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC1155Tradable
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help


Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC1155Mock
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help


Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Caller
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help


Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Revert
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help


Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Token
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported

For more information try --help

An unexpected error occurred:

Error: Failed to build one or more Move packages
    at SimpleTaskDefinition.action (/Users/jkpark/Work/move/language/evm/hardhat-move/src/index.ts:388:19)
    at Environment._runTaskDefinition (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:219:14)
    at Environment.run (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:131:14)
    at SimpleTaskDefinition.action (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/builtin-tasks/compile.ts:1422:7)
    at Environment._runTaskDefinition (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:219:14)
    at Environment.run (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:131:14)
    at main (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/cli/cli.ts:218:5)

[Bug] ICE invalid assign tmp local

    struct Foo {
        a: u64,
    }

    #[test]
    fun ice() {
        use Std::Vector;
        let v = Vector::empty();
        Vector::push_back(&mut v, Foo {a: 10});
        let b = Vector::borrow(&v, 0);
        while (true) {
            b = &Vector::pop_back(&mut v);
            let Foo {a: _} = *b;
        };
        Vector::destroy_empty(v);
    }

this piece of code caused "ICE invalid assign tmp local"

[account address] Cleanup multiple to string & from string implementations

I made the previous change to make 0x more prevalent in the account address outputs, but it's clear to me that there are too many ways to display the account addresses and it adds a lot of confusion.

I'm going to clean it up so that there are less implementations and that it's straightforward at that point.

[Feature Request] Improve documentation/error message about trailing semicolon

πŸš€ Feature Request

Given the example:

fun f(){return;}

... the compiler reports

adding a semicolon implicitly adds '()' value after the semicolon. That value '()' will not be reachable

But the documentation says:

The unit value '()' does not result in any runtime value ( https://diem.github.io/move/tuples.html )

This is confusing, specifically for new users which are not acquainted with the Rust-style syntax of Move,

[Collected from Aptos user forum]

[evm] reverts with "transaction ran out of gas"

the issue with "transaction ran out of gas" appears again.

this time, array arguments in external calls are suspicious.

See the following in ExternalCall.test.js:

        // TODO: Error with "Transaction ran out of gas"
        // it('receiver reverting with error message', async function () {
        //     const ids = [1,2,3];
        //     const amounts = [10, 100, 1000];
        //     const data = '0x42';
        //     const receiver = await ERC1155Receiver.new(RECEIVER_SINGLE_MAGIC_VALUE, false, RECEIVER_BATCH_MAGIC_VALUE, true);
        //     await expectRevert(
        //         this.externalCall.doSafeBatchTransferAcceptanceCheck(this.externalCall.address, this.externalCall.address, receiver.address, ids, amounts, data),
        //         'err_reason',
        //     );
        // });
        // TODO: Error with "Transaction ran out of gas"
        // it('receiver reverting without error message', async function () {
        //     const ids = [1,2,3];
        //     const amounts = [10, 100, 1000];
        //     const data = '0x42';
        //     const receiver = await ERC721Receiver.new(RECEIVER_MAGIC_VALUE, Error.Panic);
        //     await expectRevert(
        //         this.externalCall.doSafeBatchTransferAcceptanceCheck(this.externalCall.address, this.externalCall.address, receiver.address, ids, amounts, data),
        //         'err_data',
        //     );
        // });

[Feature Request] Read the script signature in session

πŸš€ Feature Request

Motivation

To correctly execute a script, we need to have the signature of the script to (1) validate the script has the correct signature and (2) to determine how to add a signer into the args.

Now, there is already support for the script_function (some previous discussion happens here diem/move#209). However, we still need a "load_script" function to provide similar functionalities.

[Feature Request] Unit tests need stronger abort code support

As highlighted in #127, abort_code annotation in unit tests is not super expressive. We should support

  • Location (The module that gave the abort)
  • More general major + sub status

For the location, suggested syntax:

#[test(abort_code = 0x42::M::2)]
// or
#[test(abort_code = 2, abort_location = 0x42::M)]

Note: annotation support is lacking for this right now

For status codes, suggested syntax:

#[test(status_code = "VECTOR_OPERATION_ERROR", sub_status = 1)]

[vectors] stdlib tests fail on CI

Possibly because Move unit test when embedded in Rust tests don't lead to a test failure, we have a few vector test failures which sneaked into the main branch. From running move-stdlib tests:

[ FAIL    ] 0x1::VectorTests::borrow_out_of_range
[ FAIL    ] 0x1::VectorTests::destroy_non_empty
[ FAIL    ] 0x1::VectorTests::pop_out_of_range
[ FAIL    ] 0x1::VectorTests::swap_empty
[ FAIL    ] 0x1::VectorTests::swap_out_of_range

Those failures do not need lead to Rust test failure, and therefore passed by CI.

The failures have this funny shape:

β”Œβ”€β”€ borrow_out_of_range ──────
β”‚ error[E11001]: test failure
β”‚    β”Œβ”€ /home/wrwg/gh/move/language/move-stdlib/./tests/VectorTests.move:97:9
β”‚    β”‚
β”‚ 94 β”‚     fun borrow_out_of_range() {
β”‚    β”‚         ------------------- In this function in 0x1::VectorTests
β”‚    Β·
β”‚ 97 β”‚         V::borrow(&v, 1);
β”‚    β”‚         ^^^^^^^^^^^^^^^^ Test did not abort with expected code. Expected test to abort with 1 but instead it aborted with 1 here
β”‚ 
β”‚ 
└──────────────────

So 1 was expected as an abort code but 1 was found...

Perhaps the failures are related to the new vector operations introduced in #37.

I'm rolling up PR #125 to fix the issue that Move unit tests don't produce a test failure, but will have to disable some tests temporarily.

[evm] variable capture issue in `move-to-yul`

The function ExternalCall::test_for_move_to_yul in hardhat-examples/contracts/ExternalCall/sources/ raises the following error. The error only occurs when the function is set to be callable.

#[callable]
    public fun test_for_move_to_yul(from: address, to: address, tokenId: U256, data: vector<u8>) {
        // TODO: Uncomment the following line to see the error. The error occurs only when this function is set to be `callable`.
        let _ = IERC721Receiver_try_call_onERC721Received(to, sender(), from, tokenId, data);
    }
Error: Warning: Yul is still experimental. Please use the output with care.
Error: Variable name $field_ptr already taken in this scope.
   --> <stdin>:162:25:
    |
162 |                         let $field_ptr := $LoadU256(add($field_ptr, 0))
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Error: Variable name $field_ptr already taken in this scope.
   --> <stdin>:169:25:
    |
169 |                         let $field_ptr := $LoadU256(add($field_ptr, 0))
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Error: Variable name $field_ptr already taken in this scope.
   --> <stdin>:176:25:
    |
176 |                         let $field_ptr := $LoadU256(add($field_ptr, 0))
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Error: Variable name $field_ptr already taken in this scope.
   --> <stdin>:183:25:
    |
183 |                         let $field_ptr := $LoadU256(add($field_ptr, 0))
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

RUSTSEC in dependencies in branch main

Found RUSTSEC in dependencies in job https://github.com/move-language/move/actions/runs/2155593820

    Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
      Loaded 404 security advisories (from /opt/cargo/advisory-db)
    Updating crates.io index
    Scanning Cargo.lock for vulnerabilities (487 crate dependencies)
Crate:         chrono
Version:       0.4.19
Title:         Potential segfault in `localtime_r` invocations
Date:          2020-11-10
ID:            RUSTSEC-2020-0159
URL:           https://rustsec.org/advisories/RUSTSEC-2020-0159
Solution:      No safe upgrade is available!
Dependency tree: 
chrono 0.4.19
β”œβ”€β”€ x 0.1.0
β”œβ”€β”€ tera 1.7.1
β”‚   └── move-prover-boogie-backend 0.1.0
β”‚       β”œβ”€β”€ move-to-yul 0.1.0
β”‚       β”‚   β”œβ”€β”€ move-unit-test 0.1.0
β”‚       β”‚   β”‚   β”œβ”€β”€ move-table-extension 0.1.0
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ move-vm-test-utils 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ test-generation 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-vm-integration-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-unit-test 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-transactional-test-runner 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-vm-transactional-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-ir-compiler-transactional-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-compiler-transactional-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   └── bytecode-verifier-transactional-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   └── language-benchmarks 0.1.0
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ move-vm-integration-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ move-unit-test 0.1.0
β”‚       β”‚   β”‚   β”‚   └── move-cli 0.1.0
β”‚       β”‚   β”‚   β”‚       β”œβ”€β”€ move-transactional-test-runner 0.1.0
β”‚       β”‚   β”‚   β”‚       β”œβ”€β”€ move-table-extension 0.1.0
β”‚       β”‚   β”‚   β”‚       └── move-stdlib 0.1.0
β”‚       β”‚   β”‚   β”‚           β”œβ”€β”€ test-generation 0.1.0
β”‚       β”‚   β”‚   β”‚           β”œβ”€β”€ move-vm-integration-tests 0.1.0
β”‚       β”‚   β”‚   β”‚           β”œβ”€β”€ move-unit-test 0.1.0
β”‚       β”‚   β”‚   β”‚           β”œβ”€β”€ move-transactional-test-runner 0.1.0
β”‚       β”‚   β”‚   β”‚           β”œβ”€β”€ move-to-yul 0.1.0
β”‚       β”‚   β”‚   β”‚           β”œβ”€β”€ move-table-extension 0.1.0
β”‚       β”‚   β”‚   β”‚           β”œβ”€β”€ move-stackless-bytecode 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ spec-flatten 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ read-write-set 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   └── move-cli 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ prover-mutation 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ prover-lab 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-to-yul 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-stackless-bytecode-interpreter 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”œβ”€β”€ move-unit-test 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”œβ”€β”€ move-transactional-test-runner 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”œβ”€β”€ move-prover 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”œβ”€β”€ spec-flatten 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”œβ”€β”€ prover-mutation 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”œβ”€β”€ prover-lab 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”œβ”€β”€ move-stdlib 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”œβ”€β”€ move-errmapgen 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-stdlib 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-prover 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-package 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-table-extension 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-stdlib 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”‚   β”‚   └── move-cli 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”‚   └── move-cli 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”œβ”€β”€ move-docgen 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-stdlib 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-prover 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”‚   └── move-package 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   β”œβ”€β”€ move-cli 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚   └── move-abigen 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚       β”œβ”€β”€ move-prover 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”‚       └── move-package 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   └── bytecode-interpreter-testsuite 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-prover-boogie-backend 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-prover 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   └── move-docgen 0.1.0
β”‚       β”‚   β”‚   β”‚           β”œβ”€β”€ move-compiler 0.0.1
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ test-generation 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ spec-flatten 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-vm-runtime 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”œβ”€β”€ test-generation 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”œβ”€β”€ move-vm-test-utils 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”œβ”€β”€ move-vm-integration-tests 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”œβ”€β”€ move-unit-test 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”œβ”€β”€ move-transactional-test-runner 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”œβ”€β”€ move-table-extension 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”œβ”€β”€ move-stdlib 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”œβ”€β”€ move-stackless-bytecode-interpreter 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”œβ”€β”€ move-cli 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   β”œβ”€β”€ move-async-vm 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”‚   └── language-benchmarks 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-vm-integration-tests 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-unit-test 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-transactional-test-runner 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-to-yul 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-table-extension 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-stdlib 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-prover 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-package 0.1.0
β”‚       β”‚   β”‚   β”‚           β”‚   β”œβ”€β”€ move-model 0.1.0

[design][vm] Alternative implementation of values

This note suggests a different, potentially more efficient, simpler and 100% safe implementation of the VMs value representation. The sketched design is influenced by the recent implementation of Move on the EVM.

There are three major components to this alternative model:

  • Use byte addressable linear memory to reason about Move values and references
  • Make access to this memory fast via unsafe *mut, but ensure the public value API is safe.
  • Erase runtime type information from values, up to the extent safe representation can be guaranteed. Bytecode verification Β  should already guarantee type correctness. Β If the bytecode is not type-correct, VM execution will still be safe, but the result undetermined.

Basic Model

Borrow semantics is a model for linear addressable memory, including pointer indirection and address arithmetic. The claim here is that even though this model is tailored for microprocessors, it is also the best for a virtual machine.

Given this approach, values are simply represented as regions of linear memory. The interpretation of the data in this memory is discussed later.

struct Value<'a>(*mut[u8], PhantomData<&'a ()>);

The lifetime 'a here is bound to a heap of values, e.g.associated with a Move VM session. The implementation ensures safety for all usages of Value<'a>, guaranteed by Rust lifetime checking. The heap can be a simple arena, as sessions are short living. (This is how the EVM does it.), but more investigation is needed here. Similar to the heap, there is a stack frame which is also linear addressable, as well as slots for global values.

Types and Conversions

Values are opaque. One needs a type to interpret a value., e.g.

let val: Value<'a>;
U8_TYPE.write(val, U8_TYPE.read(val)? + 1)?;

For native functions, types are either known statically, or are passed as parameters if those functions are generic.

We expect that conversion via types is safe. However, because of erasure of type information from values, only restricted forms of runtime checks can be performed (e.g. if the value's memory slice has the correct size). In case the wrong type is used on a value, this will be always safe for Rust, but may result in undetermined values for Move.

We otherwise expect that conversions should be very fast. Specifically, Rust already has builtin primitives to convert [u8,N] into a u8/u64/u128; this can be expected to compile to single machine instructions.

Structs and Vectors

A struct is represented by a slice of memory where the field data is packed into consecutive bytes. That is if the struct has two consecutive u8 and u128 fields, the first one will occupy the first byte and the 2nd one the remaining 16 bytes; the size of the struct value's memory slice thus is 17.

Borrowing a field from a struct is then simply sub-slicing the struct's slice (Value(r) => Value(r[offs..offs+size])).

Vectors, because they are dynamically sized, need to be represented by a reference to some other place on the heap, that is as an embedded Value<'a>. How can we ensure safety if we read such a value from a struct? The answer here is to simply range check whether the memory slice represented by the read value is defined for the currently allocated Rust memory of the heap. Β One simple solution for being able to do so is to never give memory allocated for values back to Rust for the `'a' lifetime. This is adequate because sessions are short living.

For nested structs, two options exist: they can be inlined, or they can be represented similar like vectors via an embedded value. Both approaches have advantages and disadvantages: the first is faster and more compact for access, but also makes moving the nested struct requiring a memcpy.

Evaluation

In the current VM implementation, values are represented by nested Rust enums:

enum ValueImpl {
Β  Β  U8(u8),
Β  Β  U64(u64),
Β  Β  ...
Β  Β  Container(Container),
}

enum Container { 
Β  Β  Locals(Rc<RefCell<Vec<ValueImpl>>>),
Β  Β  Vec(Rc<RefCell<Vec<ValueImpl>>>),
Β  Β  ...
}

This representation leads to multiple indirections and memory allocations, and heavy case switching in the code. The suggested representation is expected to be significantly more compact and efficient regards access and mutation. It should moreover be able to minimize memory fragmentation, specifically if an arena style allocator is used, which can be very important for performance of modern processor architectures.

[evm] ExternalResult does not pass the reason string correctly

See ExternalCall.move.

As the "TODO" says, it's expected to revert with the reason string which come from the callee. However, it reverts without any string.

// TODO: The following lines results in reverting without a reason string.
//       However, it is expected to revert with "ERC721ReceiverMock: reverting".
 let reason = ExternalResult::unwrap_err_reason(result);
 abort_with(reason);

[Bug] Solidity tests don't work for me

πŸ› Bug

Not sure I have the wrong version of the solidity compiler. I installed it from node like this https://docs.soliditylang.org/en/v0.8.13/installing-solidity.html#npm-node-js

It's possible it requires a specific version, but just trying to make sure all the tests pass!

To reproduce

Code snippet to reproduce

cargo test

Stack trace/error message

test run_all::dev_address/args.evm.txt ... FAILED
Error: Expected output differs from actual output:
Command `package build -v -d --arch ethereum`:
COMPILING A to Yul
GENERATING EVM bytecote from Yul
ERROR Failed to generate EVM bytecote
Error: error: unknown option '--strict-assembly'

Expected Behavior

Working tests :)

System information

Please complete the following information:

  • Commit 2771ee6
  • Rust 1.60
  • MacOS 12.3.1

Tracking Issue for Hardening the Toolings Related to Move on EVM

  • #106
  • Unify move --ethereum package build and move package test --evm
  • Update the documentation for move-cli
  • Remove build dir before starting a new build
  • Potential bug: cli tests rebuild_after_touching_manifest may fail (due to a preexisting build directory?)
  • Review: naming of certain things
    • --arch ethereum/move/async-move
    • feature evm-backend
  • Documentation for move-cli and move-package
  • move-cli/move-package: stdout vs stdin
  • move-cli/move-package: should inherit color settings
  • Bug: move package test panics when cache is hot

[evm] `ExternalResult::is_ok(&result)` is always true.

See ExternalCall.move.

In the following code, it always falls into the ok branch:

// TODO: the following code always aborts with "ok".
            // if (ExternalResult::is_ok(&result)) {
            //     abort_with(b"ok");
            // } else if (ExternalResult::is_err_reason(&result)) {
            //     abort_with(b"err_reason");
            // } else if (ExternalResult::is_err_data(&result)) {
            //     abort_with(b"err_data");
            // } else if (ExternalResult::is_panic(&result)) {
            //     abort_with(b"panic");
            // } else {
            //     abort_with(b"other");
            // }

However, it works fine if the "ok" branch is put at the end as follows:

// The following code works fine.
            if (ExternalResult::is_err_reason(&result)) {
                abort_with(b"err_reason");
            } else if (ExternalResult::is_err_data(&result)) {
                abort_with(b"err_data");
            } else if (ExternalResult::is_panic(&result)) {
                abort_with(b"panic");
            } else if (ExternalResult::is_ok(&result)) {
                abort_with(b"ok");
            } else {
                abort_with(b"other");
            }

[Feature Request][package system] Better support for propagating options defined in Move.toml

Right now, various places in the package system and CLI (e.g. running builds, tests, or the prover) have no way to access any options which might have been defined in the Move.toml, like language flavor, bytecode version, or other compiler or tool chain flags. This is because there is no design in place for sharing such global config info; rather there are a lot of static functions or struct methods on different data types. As an ugly workaround, we use environment variables like MOVE_BYTECODE_VERSION.

We should device a configuration model which gives uniform access to command line flags, configuration files, and Move.toml from everywhere. We may also want to leverage clap's capabilities to aggregate option structs to not have to redefine flags from independent tools for the package system.

[evm] external call gets "Error: Returned error: Transaction ran out of gas"

The following test in hardhat-examples/test/ExternalCall.test.js fails.

describe('Receiver', function () {
        it('receiver test', async function () {
            const receiver = await Receiver.new(RECEIVER_MAGIC_VALUE, Error.None);
            const receipt = await this.externalCall.doSafeTransferAcceptanceCheck(this.externalCall.address, receiver.address, 5042, '0x42');
        });
    });

The failure message is as follows:

1) Contract: ExternalCall
       Receiver
         receiver test:
     Error: Returned error: Transaction ran out of gas
      at Context.<anonymous> (test/ExternalCall.test.js:71:53)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (internal/process/task_queues.js:97:5)

[Bug] move-dissassembler panicked over out-of-bound error

πŸ› Bug

If a generic function contains a generic borrow of a struct that takes N type parameters Ty1, Ty2, ..., TyN, then all the type parameters have to appear as the first N type parameters of the function. Otherwise, the move-dissasembler cannot generate the string represenation of the borrowed type in struct_type_info() function in disaseembler.rs.

To reproduce

Here is an MWE that demonstrates the problem.

After compilation, the FooAX module can be dissembled by move-dissasembler.

address 0x1 {
module FooAX {
  struct C<T: copy + store + drop> has key { f: T }
  fun foo<A: copy + store + drop, X>(x: X): X acquires C { 
      let _ = borrow_global<C<A>>(@0x1); 
      x
  }
}
}

But move-disassembler failed to show the bytecode of the almost identical module FooXA:

address 0x1 {
module FooXA {
  struct C<T: copy + store + drop> has key { f: T }
  fun foo<X, A: copy + store + drop>(x: X): X acquires C {  // The order changes
      let _ = borrow_global<C<A>>(@0x1); 
      x
  }
}
}

The error info is:

thread 'main' panicked at 'Unable to dissassemble: Type parameter index 1 out of bounds while disassembling type signature', language/tools/move-disassembler/src/main.rs:128:58
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Expected Behavior

move-dissembler should be able to handle both.

Additional context

After some inspection of the source code, I found that when disassemble_instruction() sees a BorrowGlobalGeneric, it uses struct_type_info(), where signature has index not within the length of struct_source_map.type_parameters, which causes the error.

[Feature Request]TypeTable

πŸš€ Feature Request

Motivation

I have mentioned the idea of TypeTable in the documentation of Table, and I describe it in more detail here.

According to the implementation of Table(#150), we get:

module Std::Table {
    native struct Table<K, V: store> has store;
    native fun create<K, V>(): Table<K, V>
    native fun destroy<K, V>(t: Table<K, V>);
    native fun insert<K, V>(t: &mut Table<K, V>, k: &K, v: V);
    native fun remove<K, V>(t: &mut Table<K, V>, k: &K): V;
    native fun contains_key<K, V>(t: &Table<K, V>, k: &K): bool;
    native fun borrow<K, V>(t: &Table<K, V>, k: &K): &V;
    native fun borrow_mut<K, V>(t: &mut Table<K, V>, k: &K): &mut V;
}

But this Table can only use type K's value as the key, not type K as the key like borrow_global.

So I suggest introducing TypeTable with the basic operations described below:

module Std::TypeTable {
   native struct TypeTable has store;
   native fun create(): TypeTable
   native fun destroy(t: TypeTable);
   native fun insert<T>(t: &mut TypeTable, v: T);
   native fun remove<T>(t: &mut TypeTable<K>): T;
   native fun contains_key<T>(t: &TypeTable<T>): bool;
   native fun borrow<T>(t: &TypeTable): &T;
   native fun borrow_mut<T>(t: &mut TypeTable<T>): &mut T;
}

Now, we can define a AccountStorage struct in Move:

module Std::Account{
   struct AccountStroage{
      resources: TypeTable,
      moudles: Table<Identifer,vector<u8>>,
   }
}

Then we bind the table when Account create, such as:

module Std::Account{
    public fun create_account(addr: address){
        let resources = TypeTable::create();
        let modules = Table::create<Identifer,vector<u8>>();
        let account_storage = AccountStorage{
            resources,
            modules,
         };
         native_save_account(addr,account_storage);
    }

    public fun borrow<T>(addr:address):&T{
      let account_storage = native_get_account_staroge(addr);
      //This expression is not available in the current Move
      //We can not return ref like this, but we can ignore it now.
      return TypeTable::borrow<T>(&account_storage.resources);
    }

    public fun move_to<T>(signer:&signer, t:T){
      //if do not want to limit signer, can use address.
      let addr = Signer:address_of(signer);
      let account_storage = native_get_account_staroge(addr);
      TypeTable::insert(&mut account_storage.resources,t);
    }
   
    //We can update or deploy code in Move now, like `create2` in ethereum.
    public fun update_module(signer:&signer, name:Identifer, code:vector<u8>){
       let account_storage = native_get_account_staroge(addr);
       account_storage.modules.insert(name, code);
    }
}
  • Now, borrow_global(address) = Account::borrow(address),
    and move_to(siger) = Account::move_to(siger), global_storage operation can been eliminate.
  • The transaction ChangeSet are all table_changes.
  • Every Move chain framework can customize their own account storage via the TypeTable and native function.

This feature can implement via an extension like Table and the backend storage is the same as Table, but TypeTable needs the same security guarantees as borrow_global.

We have two approaches to achieving this goal:

  1. Introduce TypeTable into core instead of extension, add security restrictions to TypeTable::borrow similar to borrow_global.
  2. Introduce the visibility of Struct and let the smart contract developer can control the access of Struct, see issue #139.

Migrate from diem/move, previous discussion diem/move#158

[Bug] Module republish ends with wrong execution result

Before publish a module, vm checks if it’s abi compatible with existing one. (https://github.com/diem/move/blob/180a066094704b2411d3970758b2a05d2e406213/language/move-vm/runtime/src/runtime.rs#L115)
vm has a loader that caches the deserialized module if it’s loaded before otherwise it loads from the data cache. (https://github.com/diem/move/blob/180a066094704b2411d3970758b2a05d2e406213/language/move-vm/runtime/src/loader.rs#L841)
a successful module publish goes to data cache directly but does not invalidate the loader’s cache. (https://github.com/diem/move/blob/180a066094704b2411d3970758b2a05d2e406213/language/move-vm/runtime/src/runtime.rs#L193)
to reproduce the bug, imagine there’re 3 txn tries to publish the same module with different version V1, V2, V3. V1 is compatible with V2 and V3, but V2 is not compatible with V3.
if they’re executed in a single block, [V1, V2, V3], the following happens

  • vm publishes V1 to data cache
  • vm loads V1 in loader cache to do compatibility check with V2
  • vm publishes V2 to data cache
  • vm loads V1 (instead of V2 !!) from loader cache to do compatibility check with V3 and wrongly passes the check and publishes it

[Feature Request] Move-compiler needs to support Callback/Interact function, which is convenient for platform expansion without FS.

πŸš€ Feature Request

Move-compiler needs to support Callback/Interact function, which is convenient for platform expansion without FS.

Motivation

I need to implement a Move build in a web browser.

But the browser does not support file operations, compiling move-compiler to wasm-unkown-unkown will fail because it cannot read the file. The solution of the pontem-network team is to let move-compiler provide compilation Callback/Interact, and then wasm implements the file access interface separately. Related Commit: pontem-network/diem@11ae64b

But now move-language/move has no Callback/Interact function.

Pitch

Describe the solution you'd like
Merge commit: pontem-network/diem@11ae64b

Describe alternatives you've considered
Rust supports registering custom filesystems

Are you willing to open a pull request? (See CONTRIBUTING)
No

Additional context

My issue: starcoinorg/starcoin#3363
Access FS fail in wasm:
image

[Feature Request] Movey, a package metadata repository for Move, features and designs

Goals

Right now Move uses the move-cli to create and manage packages. The goal of this proposal is to provide a website in addition to the CLI for more transparency and more easily accessible package pages like Rubygems or Crates.io

  • User can create and manage packages using the CLI (as before).
  • [New] User can publish the metadata to the website using the CLI.
  • [New] New website allows user to search, browse, and visit packages.
  • [New] Package page showing various metadata like author, download counts, readme, etc.
  • [New] Allow user to login with Github oauth and publish their packages via the CLI to the website.
  • [New] Automatically submit metadata when a user pulls dependencies through the CLI.
  • [Planned] Link Github user profile with their uploaded packages.
  • [Planned] Consolidate different modules run in different networks into a single module page. (Draft)

At the time of writing, the logic for interacting and getting package info from multiple blockchains is rather unclear. Therefore, the website current goal is to act as a central metadata hub for packages hosted on Github only.

Design

The website uses an in-house design. You can see it at https://www.figma.com/file/mGLv9qI5n1XSVJickhLuQD/Movey

How to publish

Changes we have made to Move-CLI
Before you use the new command to upload metadata to Movey make sure your package has been pushed to Github and the remote must be named β€œorigin”.
Step 1: Navigate to the folder containing your package.
Step 2: Run the following command:
move package upload

What is lacking

Right now Movey is only a metadata hub, all the heavy work of pulling or version control of packages rely on Github. Maybe expansion on hosting Move own dependencies in the future?
Should Movey run check on every single package it knows to ensure it's a valid package and there's no malicious code?
Security could be enhanced by adding apikey to prevent unauthorized calls.

Community feedback

Right now Movey is a closed source project, however we would like to hear what the community has to say. We do plan to go open source in the near future.

[Feature Request]Introduce Visibility to Struct

πŸš€ Feature Request

Motivation

Currently, Move's structs use implicit visibility, e.g.

struct Foo{
   f1: u64,
}

is equivalent to.

public struct Foo{
   private f1: u64, 
}

Also, an implicit global storage access restriction is used to ensure that a struct can only be borrowed in the module in which it is defined.

This is actually equivalent to a conditional visibility constraint and has the same effect as adding a private visibility constraint to the struct.

private struct Foo has key{
}

So I propose to introduce the visibility of structs. This leaves it up to the smart contract developer to decide on access control for the global storage and the struct fields.

For example.

module MyModule {

   public struct Foo has key{
        public f1:u64,
   }

   private struct Bar has key{
        f1:u64,
   }
  
   public fun do_some(){
       let foo = borrow_global<Foo>();
       let bar = borrow_global<Bar>();
      // Both of these work 
   }
}

module XXX {
    use MyModule::Foo;
    public fun so_some(){
        let foo = borrow_global<Foo>();
        let f1 = foo.f1

        let bar = borrow_global<Bar>();
        // the first one will succeed, the second one will fail
    }
}

Of course, compatibility is a bigger problem, this is just an idea. If it works, I can do more work on it.

Migrate from diem/move, previous discussion diem/move#157

[evm] Element-wise vector comparison costs too much gas

this causes the gas test fail in the ERC1155(721) testsuite

  // TODO: exceeded the gas limit (30560 > 30000)
        (*Vector::borrow(&interfaceId, 0) == *Vector::borrow(&id165, 0) &&
            *Vector::borrow(&interfaceId, 1) == *Vector::borrow(&id165, 1) &&
            *Vector::borrow(&interfaceId, 2) == *Vector::borrow(&id165, 2) &&
            *Vector::borrow(&interfaceId, 3) == *Vector::borrow(&id165, 3)
        ) ||
        (*Vector::borrow(&interfaceId, 0) == *Vector::borrow(&id1155, 0) &&
            *Vector::borrow(&interfaceId, 1) == *Vector::borrow(&id1155, 1) &&
            *Vector::borrow(&interfaceId, 2) == *Vector::borrow(&id1155, 2) &&
            *Vector::borrow(&interfaceId, 3) == *Vector::borrow(&id1155, 3)
// TODO: Exceeds the gas limit (33834 > 30000)
        // ERC721Metadata (5b5e139f)
        (*Vector::borrow(&interfaceId, 0) == 91 &&
            *Vector::borrow(&interfaceId, 1) == 94 &&
            *Vector::borrow(&interfaceId, 2) == 19 &&
            *Vector::borrow(&interfaceId, 3) == 159
        ) ||
        // ERC165
        (*Vector::borrow(&interfaceId, 0) == 1 &&
            *Vector::borrow(&interfaceId, 1) == 255 &&
            *Vector::borrow(&interfaceId, 2) == 201 &&
            *Vector::borrow(&interfaceId, 3) == 167
        ) ||
        // ERC721
        (*Vector::borrow(&interfaceId, 0) == 128 &&
            *Vector::borrow(&interfaceId, 1) == 172 &&
            *Vector::borrow(&interfaceId, 2) == 88 &&
            *Vector::borrow(&interfaceId, 3) == 205
        )

[evm] implement `Evm::tokenURI_with_baseURI`

to get tokenURI with base URI.

In Solidity, it's
bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";

Basically, we want to mirror the following Solidity function in Move:

function uri(uint256 _tokenid) override public pure returns (string memory) {
        return string(
            abi.encodePacked(
                "https://ipfs.io/ipfs/bafybeihjjkwdrxxjnuwevlqtqmh3iegcadc32sio4wmo7bv2gbf34qs34a/",
                Strings.toString(_tokenid),".json"
            )
        );
    }

or

function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

[Feature Request][Table] Lifetime support? Let table take K instead of &K?

πŸš€ Feature Request

I'm not quite sure what I'm asking in practice. Maybe taking the key by value (and require K: copy).

Motivation

This doesn't compile because "Invalid return. Local variable 'bucket_idx' is still being borrowed.".
A similar thing can be done easily in Rust.

module AptosFramework::BucketedVector {
    use AptosFramework::Table;
    use Std::Vector;

    struct BucketedVector<V> has store {
        bucket_size: u64,
        buckets: Table::Table<u64, vector<V>>
    }

    public fun borrow<T: store>(vec: &BucketedVector<T>, idx: u64): &T {
        let bucket_idx = idx / vec.bucket_size;
        let item_idx = idx % vec.bucket_size;

        let bucket = Table::borrow(&vec.buckets, &bucket_idx);
        Vector::borrow(bucket, item_idx)
    }
}

Pitch

Describe the solution you'd like
Make it work so we can implement a BucketedVector.

Describe alternatives you've considered
Let user code manage the buckets directly.

Are you willing to open a pull request? (See CONTRIBUTING)
I'm not able to.

[Feature Request] Movey, a package metadata repository for Move, features and designs

Goals

Right now Move uses the move-cli to create and manage packages. The goal of this proposal is to provide a website in addition to the CLI for more transparency and more easily accessible package pages like Rubygems or Crates.io

  • User can create and manage packages using the CLI (as before).
  • [New] User can publish the metadata to the website using the CLI.
  • [New] New website allows user to search, browse, and visit packages.
  • [New] Package page showing various metadata like author, download counts, readme, etc.
  • [New] Allow user to login with Github oauth and publish their packages via the CLI to the website.
  • [New] Automatically submit metadata when a user pulls dependencies through the CLI.
  • [Planned] Link Github user profile with their uploaded packages.
  • [Planned] Consolidate different modules run in different networks into a single module page. (Draft)

At the time of writing, the logic for interacting and getting package info from multiple blockchains is rather unclear. Therefore, the website current goal is to act as a central metadata hub for packages hosted on Github only.

Breakdown of feature proposal:

- Scenario 1: A user writes a new Move package and then use the move-cli tool to upload/publish the package to get recognized in the Movey registry. In order to do this we added a new command (upload) to call an api request to Movey with the package's metadata info (name, version, description, github, rev,...) and store it as a new package record.
Question:

  • Does this approach make sense to you, or do you have a more orthodox way in mind?
  • Movey may also provide each registered user with an api token, and we plan to integrate it to the move-cli tool (either via environment variable or a config file), then sends it along with the upload request so that Movey can recognize the user and set them as the package owner. Is this preferable or do you have any suggestion of wrapping this?

- Scenario 2: A user uses move-cli tool to fetch existing dependencies for a Move package they are working on. We hook into the process and sends an api request to move-cli to register a "download" for each of the existing dependency package. If it's already registered on Movey, we increase the download count. If it does not, we create a shadow record for it, starting the download with 1.
Question: Does this work with the way Move packages are managed, or is there a better way to recognize a new "download" of a package? After all, our goal is to have a metric similar to "downloads count" of crates.io or rubygems.

- Scenario 3: A user visits movey.org and view packages there / search packages in the registry, similar to crates.io . In order to support that we'll store a list of available packages that either comes from (a) Scenario 1 above (explicitly uploaded by the creator), or (b) crawling the list of all available/public Move packages somehow.
Question: Is there any way/method for us to "crawl" and get the list of all existing Move packages? Because of the nature of storing these packages/their compiled binary on chains, it would be super helpful if you can point us in a direction to accomplish this (or if it's feasible or not).

Design

The website uses an in-house design. You can see it at https://www.figma.com/file/mGLv9qI5n1XSVJickhLuQD/Movey

How to publish

Changes we have made to Move-CLI
Before you use the new command to upload metadata to Movey make sure your package has been pushed to Github and the remote must be named β€œorigin”.
Step 1: Navigate to the folder containing your package.
Step 2: Run the following command:
move package upload

What is lacking

Right now Movey is only a metadata hub, all the heavy work of pulling or version control of packages rely on Github. Maybe expansion on hosting Move own dependencies in the future?
Should Movey run check on every single package it knows to ensure it's a valid package and there's no malicious code?
Security could be enhanced by adding apikey to prevent unauthorized calls.

Community feedback

Right now Movey is a closed source project, however we would like to hear what the community has to say. We do plan to go open source in the near future.

RUSTSEC in dependencies in branch

Found RUSTSEC in dependencies in job https://github.com/move-language/move/actions/runs/3198096435

    Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
      Loaded 459 security advisories (from /opt/cargo/advisory-db)
    Updating crates.io index
    Scanning Cargo.lock for vulnerabilities (625 crate dependencies)
Crate:     chrono
Version:   0.4.19
Title:     Potential segfault in `localtime_r` invocations
Date:      2020-11-10
ID:        RUSTSEC-2020-0159
URL:       https://rustsec.org/advisories/RUSTSEC-2020-0159
Solution:  Upgrade to >=0.4.20
Dependency tree:
chrono 0.4.19
β”œβ”€β”€ x 0.1.0
β”œβ”€β”€ tera 1.16.0
β”‚   └── move-prover-boogie-backend 0.1.0
β”‚       β”œβ”€β”€ move-to-yul 0.1.0
β”‚       β”‚   β”œβ”€β”€ move-unit-test 0.1.0
β”‚       β”‚   β”‚   β”œβ”€β”€ move-table-extension 0.1.0
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ move-vm-test-utils 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ test-generation 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-vm-integration-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-unit-test 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-transactional-test-runner 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-vm-transactional-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-ir-compiler-transactional-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-compiler-transactional-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   └── bytecode-verifier-transactional-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-cli 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-transactional-test-runner 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-table-extension 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-stdlib 0.1.1
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ test-generation 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-vm-integration-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-unit-test 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-transactional-test-runner 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-to-yul 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-table-extension 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-stackless-bytecode 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ spec-flatten 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ read-write-set 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   └── move-cli 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ prover-mutation 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ prover-lab 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-to-yul 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-stackless-bytecode-interpreter 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-unit-test 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-transactional-test-runner 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   └── bytecode-interpreter-testsuite 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-prover-boogie-backend 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   └── move-prover 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”œβ”€β”€ spec-flatten 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”œβ”€β”€ prover-mutation 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”œβ”€β”€ prover-lab 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”œβ”€β”€ move-stdlib 0.1.1
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”œβ”€β”€ move-errmapgen 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”‚   β”œβ”€β”€ move-stdlib 0.1.1
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”‚   β”œβ”€β”€ move-prover 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”‚   └── move-cli 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”œβ”€β”€ move-docgen 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”‚   β”œβ”€β”€ move-stdlib 0.1.1
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”‚   β”œβ”€β”€ move-prover 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”‚   β”œβ”€β”€ move-package 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ move-table-extension 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ move-stdlib 0.1.1
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ move-cli 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”‚   β”‚   └── move-analyzer 1.0.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”‚   └── move-cli 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       β”œβ”€β”€ move-cli 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       └── move-abigen 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚           β”œβ”€β”€ move-prover 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚           └── move-package 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-compiler 0.0.1
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ test-generation 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ spec-flatten 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ prover-mutation 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ prover-lab 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-vm-runtime 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ test-generation 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-vm-integration-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-unit-test 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-transactional-test-runner 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-table-extension 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-stdlib 0.1.1
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-cli 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-async-vm 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ language-benchmarks 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   └── diem-framework-natives 0.0.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚       └── df-cli 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-vm-integration-tests 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-unit-test 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-transactional-test-runner 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-to-yul 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-stdlib 0.1.1
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-stackless-bytecode 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-prover 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-package 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ move-model 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ spec-flatten 0.1.0
β”‚       β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ read-write-set 0.1.0

[Feature Request] Make a note in setup for SOLC_EXE for solidity tests

πŸš€ Feature Request

Make a note in setup for SOLC_EXE for solidity tests

Motivation

Is your feature request related to a problem? Please describe.
I was getting really confused why it was always telling me SOLC_EXE couldn't be found, then I realized you needed the solidity compiler for some compatibility tests. It's a little weird, and just would be great to call out / make these tests run separately when I just do cargo test.

If I missed where this is mentioned in the docs lmk.

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.