Pārlūkot izejas kodu

Generate combined .contract file for Substrate

This new file format contains both the ABI and the contract code.

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 4 gadi atpakaļ
vecāks
revīzija
66ab8d013f
7 mainītis faili ar 55 papildinājumiem un 28 dzēšanām
  1. 5 0
      CHANGELOG.md
  2. 2 2
      Cargo.toml
  3. 1 1
      README.md
  4. 3 2
      docs/running.rst
  5. 1 1
      src/abi/mod.rs
  6. 4 1
      src/abi/substrate.rs
  7. 39 21
      src/bin/solang.rs

+ 5 - 0
CHANGELOG.md

@@ -2,6 +2,11 @@
 All notable changes to [Solang](https://github.com/hyperledger-labs/solang/)
 will be documented here.
 
+## [Unreleased]
+
+### Changed
+- The Substrate target produces a single .contract file
+
 ## [0.1.6]
 
 ### Added

+ 2 - 2
Cargo.toml

@@ -33,8 +33,8 @@ blake2-rfc = "0.2.18"
 phf = { version = "0.8", features = ["macros"] }
 unicode-xid = "0.2.0"
 handlebars = "3.4"
-contract-metadata = "0.1.0"
-semver = { version = "0.10.0", features = ["serde"] }
+contract-metadata = "0.2.0"
+semver = { version = "0.11.0", features = ["serde"] }
 tempfile = "3.1"
 libc = "0.2"
 tower-lsp = "0.13"

+ 1 - 1
README.md

@@ -52,6 +52,6 @@ Alternatively if you want to use the solang docker image, run:
 ```
 docker run --rm -it -v $(pwd):/sources hyperledgerlabs/solang -v -o /sources  --target substrate /sources/flipper.sol
 ```
-You will have a flipper.wasm and flipper.json. You can use these directly in
+You will have a file called flipper.contact. You can use this directly in
 the [Polkadot UI](https://substrate.dev/substrate-contracts-workshop/#/0/deploying-your-contract?id=putting-your-code-on-the-blockchain), as if your smart
 contract was written using ink!.

+ 3 - 2
docs/running.rst

@@ -149,8 +149,9 @@ directory. Write this to flipper.sol and run:
 
   solang --target substrate flipper.sol
 
-Now you should have ``flipper.wasm`` and ``flipper.json``. This can be used
-directly in the `Polkadot UI <https://substrate.dev/substrate-contracts-workshop/#/0/deploying-your-contract?id=putting-your-code-on-the-blockchain>`_, as if the contract was written in ink!.
+Now you should have ``flipper.contract``. The file contains both the ABI and contract wasm.
+It can be used directly in the
+`Polkadot UI <https://substrate.dev/substrate-contracts-workshop/#/0/deploying-your-contract?id=putting-your-code-on-the-blockchain>`_, as if the contract was written in ink!.
 
 Using solang with Solana
 ------------------------

+ 1 - 1
src/abi/mod.rs

@@ -21,7 +21,7 @@ pub fn generate_abi(
 
             let abi = substrate::metadata(contract_no, code, ns);
 
-            (serde_json::to_string_pretty(&abi).unwrap(), "json")
+            (serde_json::to_string_pretty(&abi).unwrap(), "contract")
         }
         _ => {
             if verbose {

+ 4 - 1
src/abi/substrate.rs

@@ -295,7 +295,10 @@ pub fn metadata(contract_no: usize, code: &[u8], ns: &ast::Namespace) -> Value {
     let version = Version::parse(env!("CARGO_PKG_VERSION")).unwrap();
     let language = SourceLanguage::new(Language::Solidity, version.clone());
     let compiler = SourceCompiler::new(Compiler::Solang, version);
-    let source = Source::new(hash.as_bytes().try_into().unwrap(), language, compiler);
+    let code_hash: [u8; 32] = hash.as_bytes().try_into().unwrap();
+    let source_wasm = SourceWasm::new(code.to_vec());
+
+    let source = Source::new(Some(source_wasm), CodeHash(code_hash), language, compiler);
     let mut builder = Contract::builder();
 
     // Add our name and tags

+ 39 - 21
src/bin/solang.rs

@@ -391,32 +391,50 @@ fn process_filename(
                 },
             );
         } else {
-            let bin_filename = output_file(&contract.name, target.file_extension());
+            // Substrate has a single contact file
+            if target == solang::Target::Substrate {
+                let (contract_bs, contract_ext) =
+                    abi::generate_abi(contract_no, &ns, &code, verbose);
+                let contract_filename = output_file(&contract.name, contract_ext);
 
-            if verbose {
-                eprintln!(
-                    "info: Saving binary {} for contract {}",
-                    bin_filename.display(),
-                    contract.name
-                );
-            }
+                if verbose {
+                    eprintln!(
+                        "info: Saving {} for contract {}",
+                        contract_filename.display(),
+                        contract.name
+                    );
+                }
 
-            let mut file = File::create(bin_filename).unwrap();
-            file.write_all(&code).unwrap();
+                let mut file = File::create(contract_filename).unwrap();
+                file.write_all(&contract_bs.as_bytes()).unwrap();
+            } else {
+                let bin_filename = output_file(&contract.name, target.file_extension());
 
-            let (abi_bytes, abi_ext) = abi::generate_abi(contract_no, &ns, &code, verbose);
-            let abi_filename = output_file(&contract.name, abi_ext);
+                if verbose {
+                    eprintln!(
+                        "info: Saving binary {} for contract {}",
+                        bin_filename.display(),
+                        contract.name
+                    );
+                }
 
-            if verbose {
-                eprintln!(
-                    "info: Saving ABI {} for contract {}",
-                    abi_filename.display(),
-                    contract.name
-                );
-            }
+                let mut file = File::create(bin_filename).unwrap();
+                file.write_all(&code).unwrap();
+
+                let (abi_bytes, abi_ext) = abi::generate_abi(contract_no, &ns, &code, verbose);
+                let abi_filename = output_file(&contract.name, abi_ext);
 
-            file = File::create(abi_filename).unwrap();
-            file.write_all(&abi_bytes.as_bytes()).unwrap();
+                if verbose {
+                    eprintln!(
+                        "info: Saving ABI {} for contract {}",
+                        abi_filename.display(),
+                        contract.name
+                    );
+                }
+
+                file = File::create(abi_filename).unwrap();
+                file.write_all(&abi_bytes.as_bytes()).unwrap();
+            }
         }
     }