-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SourceScan integration #131
Comments
@Canvinus Thanks for the details about SourceScan. I hope we can adjust SourceScan to use contract metadata, so it can handle contracts verification passively. It is not unique setup, so let me provide an example from Rust world; here is how crates publishing works in Rust at the high level:
In such case, anyone can run their own SourceScan and also verify contracts. So currently, it is a question of what details needs to be included in the contract metadata to allow SourceScan to reproduce the build without any other inputs. The current Contract Metadata is quite limited: struct ContractMetadata {
version: Option<String>,
link: Option<String>,
standards: Vec<Standard>,
}
struct Standard {
standard: String,
version: String,
} For reproducibility we need:
These are currently missing in the ContractMetadata and I would suggest to add all these details into a new section ( struct ContractMetadata {
version: Option<String>,
link: Option<String>,
standards: Vec<Standard>,
build_details: Option<BuildDetails>,
}
struct BuildDetails {
/// The exact link to the contract source code, e.g. git, archive on IPFS, etc.
///
/// Examples:
/// * `"git+https://github.com/near-DevHub/neardevhub-contract.git#335e89edec95d56a4744e7160c3fd590e41ec38e"`
/// * `"ipfs://<ipfs-hash>"`
source_code_snapshot_link: Option<Url>,
/// Reference to a reproducible build environment, e.g. Docker image reference:
/// "docker.io/sourcescan/cargo-near:0.6.0"
build_environment_ref: Option<String>,
/// Contract folder within the source code snapshot.
/// Often, it is the root of the repository, so can be omitted, but in case it is a monorepo, this is the way to specify the path to the contract folder.
contract_work_dir: Option<PathBuf>,
/// The exact command that was used to build the contract, with all the flags that could affect the final result.
build_command: ["cargo", "near", "build"]
} Factory contracts will be a challenge since they often try to embed a child contract Wasm file inside. We would need to ensure that factory contracts have Let's create a NEP extension to NEP-330 and start implementing it into near-sdk-rs, cargo-near, and SourceScan. |
Docker Integration and Permission EnhancementsDocker Engine Availability CheckCheck if Docker is installed before performing operations requiring Docker. pub fn check_docker_installed() -> color_eyre::eyre::Result<bool> {
use std::process::Command;
let output = Command::new("docker").arg("--version").output();
output.map(|o| o.status.success()).unwrap_or(false)
} User Notification: "Docker is not detected on your system. Please install Docker by following the guide at https://docs.docker.com/engine/install/." Permission Error Handling for Docker CommandsHandle permission errors by suggesting the user add themselves to the Docker group or use pub fn docker_run(args: BuildCommand) -> color_eyre::eyre::Result<()> {
let output = Command::new("docker").args(["run", ...]).output();
if let Err(e) = output {
if e.kind() == std::io::ErrorKind::PermissionDenied {
println!("Permission denied for Docker commands. Try adding your user to the Docker group with: sudo usermod -aG docker $USER. Alternatively, run the command with `sudo` to elevate privileges. Then, log out and log back in for the changes to take effect.");
}
}
Ok(())
} Suggestion Message: "Permission denied for Docker commands. Try adding your user to the Docker group with: Check Docker Image AvailabilityEnsure required Docker image is available locally, or attempt to pull it from Docker Hub. pub fn check_docker_image_available(image_name: &str) -> color_eyre::eyre::Result<bool> {
let output = Command::new("docker").args(["image", "inspect", image_name]).output();
if let Ok(o) = output {
Ok(o.status.success())
} else {
println!("Attempting to pull the latest version of the image...");
let pull_output = Command::new("docker").args(["pull", image_name]).output();
pull_output.map(|p| p.status.success()).unwrap_or(false)
}
} Image Check Message: "The required Docker image is not available. Attempting to pull the latest version of the image..." Alternative Approach: Stderr ParsingAs an additional method for error handling, parse fn parse_docker_stderr(stderr: &str) -> Result<(), String> {
if stderr.contains("permission denied") {
Err("Permission denied. Try running the command with `sudo`, or add your user to the Docker group: `sudo usermod -aG docker $USER`. Then, log out and log back in for the changes to take effect.".into())
} else if stderr.contains("Network timed out") || stderr.contains("server gave HTTP response") {
Err("Network error detected. Please check your internet connection or try again later.".into())
} else if stderr.contains("No such image") {
Err("The required Docker image is not available locally. Please ensure the image name is correct or pull it from Docker Hub.".into())
} else if stderr.contains("Cannot connect to the Docker daemon") {
Err("Cannot connect to the Docker daemon. Is the docker daemon running?".into())
} else {
Err("An unspecified error occurred while executing the Docker command. Please check the Docker command and try again.".into())
}
} |
## NEP-330: Source Metadata ## 1.2.0 - Build Details Extension ### Overview This update introduces build details to the contract metadata, containing necessary information about how the contract was built. This makes it possible for others to reproduce the same WASM of this contract. The idea first appeared in the [cargo-near SourceScan integration thread](near/cargo-near#131). ### Benefits This NEP extension gives developers the capability to save all the required build details, making it possible to reproduce the same WASM code in the future. This ensures greater consistency in contracts and the ability to verify source code. With the assistance of tools like SourceScan and cargo-near, the development process on NEAR becomes significantly easier. --------- Co-authored-by: ztsalexey <alexthebuildr@gmail.com> Co-authored-by: Alexander Fadeev <fadeevab.com@gmail.com> Co-authored-by: Robert Zaremba <robert@zaremba.ch> Co-authored-by: Vlad Frolov <frolvlad@gmail.com>
Resolves #131 --------- Co-authored-by: FroVolod <frol_off@meta.ua> Co-authored-by: dj8yf0μl <26653921+dj8yfo@users.noreply.github.com> Co-authored-by: Andrey Gruzdev <44225021+Canvinus@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jacob Lindahl <encody@users.noreply.github.com> Co-authored-by: dj8yf0μl <feepdake27@gmail.com> Co-authored-by: Vlad Frolov <frolvlad@gmail.com> Co-authored-by: dj8yf0μl <noreply@nowhere.org>
For the integration purpose, I've established a preview API server that leverages test functionality not currently available in the production API. Further in this guide, I will outline all the necessary steps for
cargo-near
to successfully utilize SourceScan verification.Preview API Server
Access the preview API server at
https://test-api.sourcescan.dev
.Docker Image for Compilation
Use the Docker image
sourcescan/cargo-near:0.6.0
for compilation. Details and the Dockerfile are available on GitHub at cargo-near-image.It's essential that
cargo-near
employs this exact image when executing thecargo near build
command. Containerizing thecargo-near deploy
process is more complex, requires several workarounds. Specifically, it requires a method to securely pass the access keys to the container. This would enable the container to execute the deploy command by using the access keys located on the host machine.cargo near build
CommandThe command for executing
cargo near build {args}
would work as:This command mounts the current directory, executes the build command with the provided arguments, and ensures the container is removed after the process.
To avoid attempting to mount the container again, the environment variable
CARGO_NEAR_NO_REPRODUCIBLE
is introduced within the container. If this environment variable is detected, the standardcargo near build
process should be executed.Deploying Smart Contracts
After compilation, deploy the smart contract to the blockchain.
SourceScan API Integration
Step 1: Creating a temporary folder on remote server
Create a temporary folder with a POST request:
Returns
The
accessToken
serves as the JWT Bearer token required to access the temporary folder, which contains the specific commit, this token is available for 10 minutes, after that the token is revoked and the temp folder is deleted. Also, it returns files such asCargo.toml
, which may act as entry points for the project compilation.Step 2: Verifying the Smart Contract
Send a POST request for verification:
networkId
: Eithermainnet
ortestnet
.accountId
: The identifier of the smart contract being verified.uploadToIpfs
: Boolean value indicating whether to upload to IPFS.entryPoint
: Selection from the entry points received in the first step.attributes
: An array containing all attributes called duringcargo near build
compilation. If no attributes were specified during compilation, send an empty array[]
.Returns
After the successful execution, the temp folder is deleted, so sending the request once again would return an error.
Verification Contracts
dev.sourcescan.near
dev.sourcescan.testnet
Verification results are accessible on BOS apps:
Compilation Errors
A STATUS 500 response includes error details to assist with troubleshooting.
(Optional) Debugging API Endpoint
Returns
WASM base64 encoded string and checksum which is base58 encoded sha256 of WASM
This endpoint could be used for debugging purposes.
(Optional) Contract Metadata
To facilitate future implementations, it is recommended to save the required information in the contract metadata. Currently, SourceScan's backend cannot work with contract metadata, but storing this information would be beneficial for future use. The necessary information includes:
This includes the repository URL, the SHA of the commit, the entry point (
Cargo.toml
), and any compilation attributes used during thecargo near build
execution.The text was updated successfully, but these errors were encountered: