Skip to content
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

When instantiate a contract, sometime fails, sometime success. #1590

Open
readygo67 opened this issue Dec 11, 2023 · 0 comments
Open

When instantiate a contract, sometime fails, sometime success. #1590

readygo67 opened this issue Dec 11, 2023 · 0 comments

Comments

@readygo67
Copy link

"oasis contracts instantiate 342 '{instantiate: { }}' --gas-limit 100000000"

fail

image

Success

image

Source Code

//! A confidential hello world smart contract.
extern crate alloc;

use oasis_contract_sdk as sdk;
use oasis_contract_sdk_storage::cell::{PublicCell,ConfidentialCell};
use oasis_contract_sdk::env::Crypto;
use std::ops::{Mul, Neg};
// use ark_std::ops::Mul;
// use ark_crypto_primitives::signature::SignatureScheme;
use bls_verify_gadget::bls::{PrivateKey, PublicKey, Parameters, Signature, hash_to_g2};
use ark_bls12_381::{Config};
use ark_ec::bls12::{Bls12, G1Affine,G1Projective,G2Projective};
use ark_ec::pairing::Pairing;
use num_traits::identities::One;

/// All possible errors that can be returned by the contract.
///
/// Each error is a triplet of (module, code, message) which allows it to be both easily
/// human readable and also identifyable programmatically.
#[derive(Debug, thiserror::Error, sdk::Error)]
pub enum Error {
    #[error("bad request")]
    #[sdk_error(code = 1)]
    BadRequest,
}

/// All possible requests that the contract can handle.
///
/// This includes both calls and queries.
#[derive(Clone, Debug, cbor::Encode, cbor::Decode)]
pub enum Request {
    #[cbor(rename = "instantiate")]
    Instantiate { },

    #[cbor(rename = "sign")]
    Sign {message: String },

    #[cbor(rename = "verify")]
    Verify {message: String, signature: String},

    #[cbor(rename = "public_key")]
    PublicKey { },
}

/// All possible responses that the contract can return.
///
/// This includes both calls and queries.
#[derive(Clone, Debug, Eq, PartialEq, cbor::Encode, cbor::Decode)]
pub enum Response {

    #[cbor(rename = "public_key")]
    PublicKey {public_key: String },

    #[cbor(rename = "signature")]
    Signature {signature: String },

    #[cbor(rename = "verify_result")]
    VerifyResult { result: bool },
}

/// The contract type.
pub struct Bls12_381Signer;


// const MASTER_SK_HEX: &str = "88c522e40e4d57abd3386ff6cb2c5496d767606488f3c9f9494cd363741d4e67";

/// Storage cell for the counter.
const PRIVATEKEYCELL: ConfidentialCell<Vec<u8>> = ConfidentialCell::new(b"private_key");
const PUBLICKEYCELL: PublicCell<Vec<u8>> = PublicCell::new(b"public_key");


// Implementation of the sdk::Contract trait is required in order for the type to be a contract.
impl sdk::Contract for Bls12_381Signer {
    type Request = Request;
    type Response = Response;
    type Error = Error;

    fn instantiate<C: sdk::Context>(ctx: &mut C, request: Request) -> Result<(), Error> {
        // This method is called during the contracts.Instantiate call when the contract is first
        // instantiated. It can be used to initialize the contract state.
        match request {
            // We require the caller to always pass the Instantiate request.
            Request::Instantiate { } => {
                let mut buf = vec![0; 32];  //need check modulus
                let bytes_written = ctx.env().random_bytes(&[], &mut buf);
                buf.truncate(bytes_written);
                PRIVATEKEYCELL.set(ctx.confidential_store(), buf.clone());

                let private_key = PrivateKey::<Config>::try_from(buf.as_slice()).expect("Invalid private key");
                let public_key = PublicKey::<Config>::from(&private_key);

                let binding:Vec<u8> = public_key.into();
                PUBLICKEYCELL.set(ctx.public_store(), binding);

                Ok(())
            }
            _ => Err(Error::BadRequest),
        }
    }

    fn call<C: sdk::Context>(ctx: &mut C, request: Request) -> Result<Response, Error> {
        // This method is called for each contracts.Call call. It is supposed to handle the request
        // and return a response.
        match request {

            Request::Sign {message} => {
                let b = PRIVATEKEYCELL.get(ctx.confidential_store()).expect("fail to get the private key byte");
                let private_key = PrivateKey::<Config>::try_from(b.as_slice()).expect("Invalid private key");

                let message_bytes = hex::decode(message).expect("fail to decode message string");
                //let message_bytes = message.into_bytes(); //"1234" => "31323334", 转换成ASCII码了
                let h = G2Projective::<Config>::from(hash_to_g2::<Config>(&message_bytes));
                let sig = Signature::<Config>::from(h.mul(private_key.private_key));
        
                
                // let private_str = String::from(MASTER_SK_HEX);
                // let private_key = PrivateKey::<Config>::try_from(private_str).expect("Invalid private key");
                // let message_bytes = message.into_bytes();
            
                // let h = G2Projective::<Config>::from(hash_to_g2::<Config>(&message_bytes));
                // let sig = Signature::<Config>::from(h.mul(private_key.private_key));

                Ok(Response::Signature {
                    signature: sig.into()
                })
            }

            Request::Verify {message, signature} => {
                let b = PUBLICKEYCELL.get(ctx.public_store()).expect("fail to get public key"); 
                // Return the greeting as a response.
                let parameters = Parameters::<Config>::default();
                let public_key = PublicKey::<Config>::try_from(b.as_slice()).expect("Invalid public key");
                let signature = Signature::<Config>::try_from(signature).expect("Invalid signature");
                let message_bytes = hex::decode(message).expect("fail to decode message string");
            
                let g1: G1Affine<Config> = parameters.g1_generator.clone().into();
                let g1_neg = G1Projective::<Config>::from(g1.neg());
                let h = G2Projective::<Config>::from(hash_to_g2::<Config>(&message_bytes));
            
                let bls_paired = Bls12::<Config>::multi_pairing([g1_neg, *public_key.as_ref()], [*signature.as_ref(), h]);

                // let parameters = Parameters::<Config>::default();
                // let public_key = PublicKey::<Config>::try_from(public_key).expect("Invalid public key");
                // let signature = Signature::<Config>::try_from(signature).expect("Invalid signature");
                // let message_bytes = message.into_bytes();
            
                // let g1: G1Affine<Config> = parameters.g1_generator.clone().into();
                // let g1_neg = G1Projective::<Config>::from(g1.neg());
                // let h = G2Projective::<Config>::from(hash_to_g2::<Config>(&message_bytes));
            
                // let bls_paired = Bls12::<Config>::multi_pairing([g1_neg, *public_key.as_ref()], [*signature.as_ref(), h]);

                
                Ok(Response::VerifyResult {
                    result: bls_paired.0.is_one()
                })
            }

            Request::PublicKey {} => {
                let public_key = PUBLICKEYCELL.get(ctx.public_store()).expect("fail to get public key"); 
                // let private_str = String::from(MASTER_SK_HEX);
                // let private_key = PrivateKey::<Config>::try_from(private_str).expect("Invalid private key");
                // let public_key = PublicKey::<Config>::from(&private_key);
               
                // Return the greeting as a response.
                Ok(Response::PublicKey {
                    public_key: hex::encode(public_key)
                })
            }

            _ => Err(Error::BadRequest),
        }
    }

    fn query<C: sdk::Context>(ctx: &mut C, request: Request) -> Result<Response, Error> {
        // This method is called for each contracts.Query query. It is supposed to handle the
        // request and return a response.
        match request {
            Request::PublicKey {} => {
                let public_key = PUBLICKEYCELL.get(ctx.public_store()).expect("fail to get public key"); 
                // Return the greeting as a response.
                Ok(Response::PublicKey {
                    public_key: hex::encode(public_key),
                })
            }

            _ => Err(Error::BadRequest),
        }
    }
}

// Create the required Wasm exports required for the contract to be runnable.
sdk::create_contract!(Bls12_381Signer);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant