mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-12 18:41:02 +00:00
Merge branch 'main' into resolc.js
This commit is contained in:
Generated
+1004
-691
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -67,7 +67,7 @@ log = { version = "0.4" }
|
|||||||
# polkadot-sdk and friends
|
# polkadot-sdk and friends
|
||||||
codec = { version = "3.6.12", default-features = false, package = "parity-scale-codec" }
|
codec = { version = "3.6.12", default-features = false, package = "parity-scale-codec" }
|
||||||
scale-info = { version = "2.11.1", default-features = false }
|
scale-info = { version = "2.11.1", default-features = false }
|
||||||
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk", rev = "2b6b69641ccff4d7aa9c32051bbb2f1e775ef8cc" }
|
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk", rev = "a77940bac783108fcae783c553528c8d5328e5b2" }
|
||||||
|
|
||||||
# llvm
|
# llvm
|
||||||
[workspace.dependencies.inkwell]
|
[workspace.dependencies.inkwell]
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||

|

|
||||||
|
[](https://contracts.polakdot.io)
|
||||||
|
|
||||||
# revive
|
# revive
|
||||||
|
|
||||||
YUL and EVM assembly recompiler to LLVM, targetting RISC-V on [PolkaVM](https://github.com/koute/polkavm).
|
YUL and EVM assembly recompiler to LLVM, targetting RISC-V on [PolkaVM](https://github.com/koute/polkavm).
|
||||||
|
|
||||||
[Frontend](https://github.com/matter-labs/era-compiler-solidity) and [code generator](https://github.com/matter-labs/era-compiler-llvm-context) are based of ZKSync `zksolc`.
|
Visit [contracts.polkadot.io](contracts.polkadot.io) to learn more about contracts on Polkadot!
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
This is experimental software in active development and not ready just yet for production usage.
|
This is experimental software in active development and not ready just yet for production usage. Please do report any compiler related issues or missing features that are [not yet known to us](https://contracts.polkadot.io/known_issues/) here.
|
||||||
|
|
||||||
Discussion around the development is hosted on the [Polkadot Forum](https://forum.polkadot.network/t/contracts-update-solidity-on-polkavm/6949#a-new-solidity-compiler-1).
|
Discussion around the development is hosted on the [Polkadot Forum](https://forum.polkadot.network/t/contracts-update-solidity-on-polkavm/6949#a-new-solidity-compiler-1).
|
||||||
|
|
||||||
@@ -55,6 +56,7 @@ Ensure that your branch passes `make test` locally when submitting a pull reques
|
|||||||
## Design overview
|
## Design overview
|
||||||
|
|
||||||
`revive` uses [solc](https://github.com/ethereum/solidity/), the Ethereum Solidity compiler, as the [Solidity frontend](crates/solidity/src/lib.rs) to process smart contracts written in Solidity. The YUL IR code (or legacy EVM assembly as a fallback for older `solc` versions) emitted by `solc` is then translated to LLVM IR, targetting [Polkadots `revive` pallet](https://docs.rs/pallet-revive/latest/pallet_revive/trait.SyscallDoc.html).
|
`revive` uses [solc](https://github.com/ethereum/solidity/), the Ethereum Solidity compiler, as the [Solidity frontend](crates/solidity/src/lib.rs) to process smart contracts written in Solidity. The YUL IR code (or legacy EVM assembly as a fallback for older `solc` versions) emitted by `solc` is then translated to LLVM IR, targetting [Polkadots `revive` pallet](https://docs.rs/pallet-revive/latest/pallet_revive/trait.SyscallDoc.html).
|
||||||
|
[Frontend](https://github.com/matter-labs/era-compiler-solidity) and [code generator](https://github.com/matter-labs/era-compiler-llvm-context) are based of ZKSync `zksolc`.
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Known issues
|
||||||
|
|
||||||
|
The following is known and we are either working on it or it is a hard limitation. Please do not open a new issue.
|
||||||
|
|
||||||
|
## Release
|
||||||
|
|
||||||
|
`0.1.0-dev-2`
|
||||||
|
|
||||||
|
## Missing features
|
||||||
|
|
||||||
|
- [Libraries with public functions are not supported](https://github.com/paritytech/revive/issues/91)
|
||||||
|
- [Automatic import resolution is not supported](https://github.com/paritytech/revive/issues/98)
|
||||||
|
- The emulated EVM linear contract memory is limited to 64kb in size. Will be fixed with support for metered dynamic memory.
|
||||||
|
- [The contract calldata is currently limited to 1kb in size](https://github.com/paritytech/revive/issues/57)
|
||||||
|
- [EIP-4844 opcodes are not supported](https://github.com/paritytech/revive/issues/64)
|
||||||
|
- [Delegate calls are not supported](https://github.com/paritytech/revive/issues/67)
|
||||||
|
- [The `blockhash` opcode is not supported](https://github.com/paritytech/revive/issues/61)
|
||||||
|
- [The `extcodesize` opcode is not supported](https://github.com/paritytech/revive/issues/58)
|
||||||
|
- [The `origin` opcode is not supported](https://github.com/paritytech/revive/issues/59)
|
||||||
|
- [Gas limits for contract calls are ignored](https://github.com/paritytech/revive/issues/60)
|
||||||
|
- [Gas related opcodes are not supported](https://github.com/paritytech/revive/issues/60)
|
||||||
|
- IPFS metadata hashes are not supported
|
||||||
|
- [Compiled contract artifacts can exceed the pallet static memory limit and fail to deploy](https://github.com/paritytech/revive/issues/96).
|
||||||
|
- [Transfers to inexistant accounts will fail if the transferred value lies below the ED.](https://github.com/paritytech/revive/issues/83) Will be fixed in the pallet to make the ED completely transparent for contracts.
|
||||||
|
|
||||||
|
## Wontfix
|
||||||
|
|
||||||
|
Please consult our documentation to learn more about Solidity and EVM features likely to remain unsupported (and why they will not be supported).
|
||||||
|
|
||||||
|
TODO: Insert link to the relevant documentation section.
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"Baseline": 967,
|
"Baseline": 961,
|
||||||
"Computation": 4022,
|
"Computation": 4024,
|
||||||
"DivisionArithmetics": 31787,
|
"DivisionArithmetics": 31789,
|
||||||
"ERC20": 44233,
|
"ERC20": 44214,
|
||||||
"Events": 1743,
|
"Events": 1737,
|
||||||
"FibonacciIterative": 2927,
|
"FibonacciIterative": 2929,
|
||||||
"Flipper": 3408,
|
"Flipper": 3402,
|
||||||
"SHA1": 26009
|
"SHA1": 26003
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
pragma solidity ^0.8;
|
||||||
|
|
||||||
|
/* runner.json
|
||||||
|
{
|
||||||
|
"differential": false,
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"Instantiate": {
|
||||||
|
"code": {
|
||||||
|
"Solidity": {
|
||||||
|
"contract": "BlockHash"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": "4545454545454545454545454545454545454545454545454545454545454545"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
contract BlockHash {
|
||||||
|
constructor(bytes32 expected) payable {
|
||||||
|
assert(blockhash(0) == expected);
|
||||||
|
assert(blockhash(1) == 0);
|
||||||
|
assert(
|
||||||
|
blockhash(
|
||||||
|
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
) == 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,6 +44,7 @@ test_spec!(transfer, "Transfer", "Transfer.sol");
|
|||||||
test_spec!(return_data_oob, "ReturnDataOob", "ReturnDataOob.sol");
|
test_spec!(return_data_oob, "ReturnDataOob", "ReturnDataOob.sol");
|
||||||
test_spec!(immutables, "Immutables", "Immutables.sol");
|
test_spec!(immutables, "Immutables", "Immutables.sol");
|
||||||
test_spec!(transaction, "Transaction", "Transaction.sol");
|
test_spec!(transaction, "Transaction", "Transaction.sol");
|
||||||
|
test_spec!(block_hash, "BlockHash", "BlockHash.sol");
|
||||||
|
|
||||||
fn instantiate(path: &str, contract: &str) -> Vec<SpecsAction> {
|
fn instantiate(path: &str, contract: &str) -> Vec<SpecsAction> {
|
||||||
vec![Instantiate {
|
vec![Instantiate {
|
||||||
|
|||||||
@@ -15,7 +15,12 @@ doctest = false
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
riscv-zbb = []
|
riscv-zbb = []
|
||||||
riscv-64 = []
|
riscv-64 = [
|
||||||
|
"revive-linker/riscv-64",
|
||||||
|
"revive-builtins/riscv-64",
|
||||||
|
"revive-runtime-api/riscv-64",
|
||||||
|
"revive-common/riscv-64",
|
||||||
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ where
|
|||||||
for import in revive_runtime_api::polkavm_imports::IMPORTS {
|
for import in revive_runtime_api::polkavm_imports::IMPORTS {
|
||||||
module
|
module
|
||||||
.get_function(import)
|
.get_function(import)
|
||||||
.expect("should be declared")
|
.unwrap_or_else(|| panic!("{import} import should be declared"))
|
||||||
.set_linkage(inkwell::module::Linkage::External);
|
.set_linkage(inkwell::module::Linkage::External);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,13 +74,24 @@ where
|
|||||||
|
|
||||||
/// Translates the `block_hash` instruction.
|
/// Translates the `block_hash` instruction.
|
||||||
pub fn block_hash<'ctx, D>(
|
pub fn block_hash<'ctx, D>(
|
||||||
_context: &mut Context<'ctx, D>,
|
context: &mut Context<'ctx, D>,
|
||||||
_index: inkwell::values::IntValue<'ctx>,
|
index: inkwell::values::IntValue<'ctx>,
|
||||||
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
|
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
|
||||||
where
|
where
|
||||||
D: Dependency + Clone,
|
D: Dependency + Clone,
|
||||||
{
|
{
|
||||||
todo!()
|
let output_pointer = context.build_alloca_at_entry(context.word_type(), "blockhash_out_ptr");
|
||||||
|
let index_ptr = context.build_alloca_at_entry(context.word_type(), "blockhash_index_ptr");
|
||||||
|
context.build_store(index_ptr, index)?;
|
||||||
|
|
||||||
|
context.build_runtime_call(
|
||||||
|
revive_runtime_api::polkavm_imports::BLOCK_HASH,
|
||||||
|
&[
|
||||||
|
index_ptr.to_int(context).into(),
|
||||||
|
output_pointer.to_int(context).into(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
context.build_byte_swap(context.build_load(output_pointer, "block_hash")?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translates the `difficulty` instruction.
|
/// Translates the `difficulty` instruction.
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ const TARGET_FLAG: &str = "--target=riscv32";
|
|||||||
const TARGET_FLAG: &str = "--target=riscv64";
|
const TARGET_FLAG: &str = "--target=riscv64";
|
||||||
|
|
||||||
#[cfg(not(feature = "riscv-64"))]
|
#[cfg(not(feature = "riscv-64"))]
|
||||||
const TARGET_ARCH_FLAG: &str = "-march=rv32em";
|
const TARGET_ARCH_FLAG: &str = "-march=rv32emac";
|
||||||
#[cfg(feature = "riscv-64")]
|
#[cfg(feature = "riscv-64")]
|
||||||
const TARGET_ARCH_FLAG: &str = "-march=rv64em";
|
const TARGET_ARCH_FLAG: &str = "-march=rv64emac";
|
||||||
|
|
||||||
#[cfg(not(feature = "riscv-64"))]
|
#[cfg(not(feature = "riscv-64"))]
|
||||||
const TARGET_ABI_FLAG: &str = "-mabi=ilp32e";
|
const TARGET_ABI_FLAG: &str = "-mabi=ilp32e";
|
||||||
@@ -36,6 +36,10 @@ fn compile(source_path: &str, bitcode_path: &str) {
|
|||||||
TARGET_TRIPLE_FLAG,
|
TARGET_TRIPLE_FLAG,
|
||||||
TARGET_ARCH_FLAG,
|
TARGET_ARCH_FLAG,
|
||||||
TARGET_ABI_FLAG,
|
TARGET_ABI_FLAG,
|
||||||
|
"-Xclang",
|
||||||
|
"-target-feature",
|
||||||
|
"-Xclang",
|
||||||
|
"+fast-unaligned-access,+xtheadcondmov",
|
||||||
"-fno-exceptions",
|
"-fno-exceptions",
|
||||||
"-ffreestanding",
|
"-ffreestanding",
|
||||||
"-Wall",
|
"-Wall",
|
||||||
|
|||||||
@@ -9,7 +9,11 @@
|
|||||||
|
|
||||||
#define POLKAVM_REGS_FOR_TY_void 0
|
#define POLKAVM_REGS_FOR_TY_void 0
|
||||||
#define POLKAVM_REGS_FOR_TY_i32 1
|
#define POLKAVM_REGS_FOR_TY_i32 1
|
||||||
#define POLKAVM_REGS_FOR_TY_i64 2
|
#ifdef _LP64
|
||||||
|
#define POLKAVM_REGS_FOR_TY_i64 1
|
||||||
|
#else
|
||||||
|
#define POLKAVM_REGS_FOR_TY_i64 2
|
||||||
|
#endif
|
||||||
|
|
||||||
#define POLKAVM_REGS_FOR_TY_int8_t POLKAVM_REGS_FOR_TY_i32
|
#define POLKAVM_REGS_FOR_TY_int8_t POLKAVM_REGS_FOR_TY_i32
|
||||||
#define POLKAVM_REGS_FOR_TY_uint8_t POLKAVM_REGS_FOR_TY_i32
|
#define POLKAVM_REGS_FOR_TY_uint8_t POLKAVM_REGS_FOR_TY_i32
|
||||||
@@ -107,6 +111,26 @@ struct PolkaVM_Metadata {
|
|||||||
unsigned char output_regs;
|
unsigned char output_regs;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
#ifdef _LP64
|
||||||
|
#define POLKAVM_EXPORT_DEF() \
|
||||||
|
".quad %[metadata]\n" \
|
||||||
|
".quad %[function]\n"
|
||||||
|
#else
|
||||||
|
#define POLKAVM_EXPORT_DEF() \
|
||||||
|
".word %[metadata]\n" \
|
||||||
|
".word %[function]\n"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _LP64
|
||||||
|
#define POLKAVM_IMPORT_DEF() \
|
||||||
|
".word 0x0000000b\n" \
|
||||||
|
".quad %[metadata]\n"
|
||||||
|
#else
|
||||||
|
#define POLKAVM_IMPORT_DEF() \
|
||||||
|
".word 0x0000000b\n" \
|
||||||
|
".word %[metadata]\n"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define POLKAVM_EXPORT(arg_return_ty, fn_name, ...) \
|
#define POLKAVM_EXPORT(arg_return_ty, fn_name, ...) \
|
||||||
static struct PolkaVM_Metadata POLKAVM_JOIN(fn_name, __EXPORT_METADATA) __attribute__ ((section(".polkavm_metadata"))) = { \
|
static struct PolkaVM_Metadata POLKAVM_JOIN(fn_name, __EXPORT_METADATA) __attribute__ ((section(".polkavm_metadata"))) = { \
|
||||||
1, 0, sizeof(#fn_name) - 1, #fn_name, POLKAVM_COUNT_REGS(__VA_ARGS__), POLKAVM_COUNT_REGS(arg_return_ty) \
|
1, 0, sizeof(#fn_name) - 1, #fn_name, POLKAVM_COUNT_REGS(__VA_ARGS__), POLKAVM_COUNT_REGS(arg_return_ty) \
|
||||||
@@ -115,8 +139,7 @@ static void __attribute__ ((naked, used)) POLKAVM_UNIQUE(polkavm_export_dummy)()
|
|||||||
__asm__( \
|
__asm__( \
|
||||||
".pushsection .polkavm_exports,\"R\",@note\n" \
|
".pushsection .polkavm_exports,\"R\",@note\n" \
|
||||||
".byte 1\n" \
|
".byte 1\n" \
|
||||||
".word %[metadata]\n" \
|
POLKAVM_EXPORT_DEF() \
|
||||||
".word %[function]\n" \
|
|
||||||
".popsection\n" \
|
".popsection\n" \
|
||||||
: \
|
: \
|
||||||
: \
|
: \
|
||||||
@@ -130,10 +153,9 @@ static void __attribute__ ((naked, used)) POLKAVM_UNIQUE(polkavm_export_dummy)()
|
|||||||
static struct PolkaVM_Metadata POLKAVM_JOIN(fn_name, __IMPORT_METADATA) __attribute__ ((section(".polkavm_metadata"))) = { \
|
static struct PolkaVM_Metadata POLKAVM_JOIN(fn_name, __IMPORT_METADATA) __attribute__ ((section(".polkavm_metadata"))) = { \
|
||||||
1, 0, sizeof(#fn_name) - 1, #fn_name, POLKAVM_COUNT_REGS(__VA_ARGS__), POLKAVM_COUNT_REGS(arg_return_ty) \
|
1, 0, sizeof(#fn_name) - 1, #fn_name, POLKAVM_COUNT_REGS(__VA_ARGS__), POLKAVM_COUNT_REGS(arg_return_ty) \
|
||||||
}; \
|
}; \
|
||||||
static arg_return_ty __attribute__ ((naked, used)) fn_name(POLKAVM_IMPORT_ARGS_IMPL(__VA_ARGS__)) { \
|
static arg_return_ty __attribute__ ((used, naked)) fn_name(POLKAVM_IMPORT_ARGS_IMPL(__VA_ARGS__)) { \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
".word 0x0000000b\n" \
|
POLKAVM_IMPORT_DEF() \
|
||||||
".word %[metadata]\n" \
|
|
||||||
"ret\n" \
|
"ret\n" \
|
||||||
: \
|
: \
|
||||||
: \
|
: \
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ POLKAVM_IMPORT(void, balance, uint32_t)
|
|||||||
|
|
||||||
POLKAVM_IMPORT(void, balance_of, uint32_t, uint32_t)
|
POLKAVM_IMPORT(void, balance_of, uint32_t, uint32_t)
|
||||||
|
|
||||||
|
POLKAVM_IMPORT(void, block_hash, uint32_t, uint32_t)
|
||||||
|
|
||||||
POLKAVM_IMPORT(void, block_number, uint32_t)
|
POLKAVM_IMPORT(void, block_number, uint32_t)
|
||||||
|
|
||||||
POLKAVM_IMPORT(uint32_t, call, uint32_t)
|
POLKAVM_IMPORT(uint32_t, call, uint32_t)
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ pub static BALANCE: &str = "balance";
|
|||||||
|
|
||||||
pub static BALANCE_OF: &str = "balance_of";
|
pub static BALANCE_OF: &str = "balance_of";
|
||||||
|
|
||||||
|
pub static BLOCK_HASH: &str = "block_hash";
|
||||||
|
|
||||||
pub static BLOCK_NUMBER: &str = "block_number";
|
pub static BLOCK_NUMBER: &str = "block_number";
|
||||||
|
|
||||||
pub static CALL: &str = "call";
|
pub static CALL: &str = "call";
|
||||||
@@ -62,12 +64,13 @@ pub static VALUE_TRANSFERRED: &str = "value_transferred";
|
|||||||
|
|
||||||
/// All imported runtime API symbols.
|
/// All imported runtime API symbols.
|
||||||
/// Useful for configuring common attributes and linkage.
|
/// Useful for configuring common attributes and linkage.
|
||||||
pub static IMPORTS: [&str; 25] = [
|
pub static IMPORTS: [&str; 26] = [
|
||||||
SBRK,
|
SBRK,
|
||||||
MEMORY_SIZE,
|
MEMORY_SIZE,
|
||||||
ADDRESS,
|
ADDRESS,
|
||||||
BALANCE,
|
BALANCE,
|
||||||
BALANCE_OF,
|
BALANCE_OF,
|
||||||
|
BLOCK_HASH,
|
||||||
BLOCK_NUMBER,
|
BLOCK_NUMBER,
|
||||||
CALL,
|
CALL,
|
||||||
CALLER,
|
CALLER,
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
book
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
[book]
|
|
||||||
authors = ["Cyrill Leutwiler <cyrill@parity.io>"]
|
|
||||||
language = "en"
|
|
||||||
multilingual = false
|
|
||||||
src = "src"
|
|
||||||
title = "revive documentation"
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# revive documentation
|
|
||||||
|
|
||||||
Welcome to the revive Solidty compiler documentation!
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Summary
|
|
||||||
|
|
||||||
[Introduction](README.md)
|
|
||||||
|
|
||||||
- [User guide](./user-guide.md)
|
|
||||||
- [Installation](./installation.md)
|
|
||||||
- [CLI guide](./cli.md)
|
|
||||||
- [Hardhat integration](./hardhat.md)
|
|
||||||
- [Architecture](./architecture.md)
|
|
||||||
- [Overview](./overview.md)
|
|
||||||
- [Runtime](./runtime.md)
|
|
||||||
- [Differences from EVM](./differences-evm.md)
|
|
||||||
- [Development](./development.md)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# Architecture
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# CLI guide
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# Development
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# Differences from EVM
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# Differences from EVM
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# Hardhat integration
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# Installation
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# Overview
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Runtime
|
|
||||||
|
|
||||||
revive compiled contract target the new contracts pallet runtime environment API.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# User guide
|
|
||||||
Reference in New Issue
Block a user