Giter Site home page Giter Site logo

boilerplate's People

Contributors

dependabot[bot] avatar freedomhero avatar gitzhou avatar msinkec avatar ram-lankada avatar xhliu avatar xonack avatar yusufidimaina9989 avatar zhfnjust 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

boilerplate's Issues

playground.scrypt.io faucet fail

Hi all,

Not sure if this is right place, but faucet is failing with message:

Getting testnet bsv from faucet
Get bsv from faucet fail.

From: "You can fund the address by running command [sCrypt: Get BSV From Faucet]"

Clean up simpleBVM

Also update documentation on inline function. Multiple, not 1, elements can be left on stack, but only 1 will remain after function return.

#68

mismatched constructor arguments not detected

new should throw, but did not.

const { buildContractClass, getPreimage, toHex, SigHashPreimage, signTx } = require('scryptlib');
const { compileContract, newTx } = require('../../helper');
const bsv = require('bsv');
const { expect } = require('chai');
const Demo = buildContractClass(compileContract('cltv.scrypt'))
const demo = new Demo();  // <--- should fail here
demo.matureTime = 1422637;
const prevRaw = "0100000001003e24d6e62578b1bdb488d572a44aa569c5e12427928e839142a4772db61d1e000000006b48304502210084b3f3193580c8636a2cfb91a2c5e8c9de15f662ab0847abbc5ef07311b0e4bc02205be32a2a63c629549029e3fd89c05ea150aa6058632b4358ed525dd59f6fc85d4121028998303fefdef0c6fce6124788d07989ca692b51fdd9e1a555038ef0f3dfe5daffffffff02e803000000000000fde0025101400315b52d6153796100792097dfd76851bf465e8f715593b217714858bbe9570ff3bd5e33840a34e20ff0262102ba79df5f8ae7604a9830f03c7933028186aede0675a16f025dc4f8be8eec0382210ac407f0e4bd44bfc207355a778b046225a7068fc59ee7eda43ad905aadbffc800206c266b30e6a1319c66dc401e5bd6b432ba49688eecd118297041da8074ce0810201008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266c59795979855679aa616100790079517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e007e81517a756157795679567956795679537956795479577995939521414136d08c5ed2bf3ba048afe6dcaebafeffffffffffffffffffffffffffffff0061517951795179517997527a75517a5179009f635179517993527a75517a685179517a75517a7561527a75517a517951795296a0630079527994527a75517a68537982775279827754527993517993013051797e527e53797e57797e527e52797e5579517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7e56797e0079517a75517a75517a75517a75517a75517a75517a75517a75517a75517a75517a75517a756100795779ac517a75517a75517a75517a75517a75517a75517a75517a75517a7561517a75616961537961610079007982775179517954947f75517958947f77517a75517a75610079007e81517a7561517a75615179a27777777702ca6a00000000001976a9149163df51f8ec631b800c48ed3dd8e970bd10ba3b88ac00000000"
const getLockingScript = (rawtx, oIdx) => { return bsv.Transaction(rawtx).outputs[oIdx] }
const lock = getLockingScript(prevRaw, 0);
const scriptCode = new bsv.Script(lock.script);
const raw = '0100000002f6bad6592d40a5b56306db093475387e94cf3e2d62a5a7d35a09fc9d1b697f0b00000000fd82034d7f030100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6bad6592d40a5b56306db093475387e94cf3e2d62a5a7d35a09fc9d1b697f0b00000000fde0025101400315b52d6153796100792097dfd76851bf465e8f715593b217714858bbe9570ff3bd5e33840a34e20ff0262102ba79df5f8ae7604a9830f03c7933028186aede0675a16f025dc4f8be8eec0382210ac407f0e4bd44bfc207355a778b046225a7068fc59ee7eda43ad905aadbffc800206c266b30e6a1319c66dc401e5bd6b432ba49688eecd118297041da8074ce0810201008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266c59795979855679aa616100790079517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e007e81517a756157795679567956795679537956795479577995939521414136d08c5ed2bf3ba048afe6dcaebafeffffffffffffffffffffffffffffff0061517951795179517997527a75517a5179009f635179517993527a75517a685179517a75517a7561527a75517a517951795296a0630079527994527a75517a68537982775279827754527993517993013051797e527e53797e57797e527e52797e5579517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7e56797e0079517a75517a75517a75517a75517a75517a75517a75517a75517a75517a75517a75517a756100795779ac517a75517a75517a75517a75517a75517a75517a75517a75517a7561517a75616961537961610079007982775179517954947f75517958947f77517a75517a75610079007e81517a7561517a75615179a277777777e803000000000000feffffff3487f9b2edd6f480081873283ad0d6348b9e4237d5e9076265d7090737f19ebc34b51500c3000000fefffffff6bad6592d40a5b56306db093475387e94cf3e2d62a5a7d35a09fc9d1b697f0b010000006a47304402204e80cf2fb18eea5965414cd31b15ab4de2545b497e903a2bc91addb4e0afd5d602200ef7e4cf140b397508561f81b4bfd160fe3633f9b106f0463fcf6906214a4c314121028998303fefdef0c6fce6124788d07989ca692b51fdd9e1a555038ef0f3dfe5dafeffffff02e8030000000000001976a9149163df51f8ec631b800c48ed3dd8e970bd10ba3b88ac1ac66a00000000001976a9149163df51f8ec631b800c48ed3dd8e970bd10ba3b88ac34b51500'
const tx = bsv.Transaction(raw);
const inputSatoshis = 1000, inputIndex = 0;
const lockingScript = scriptCode.toASM();
preimage = getPreimage(tx, lockingScript, inputSatoshis, inputIndex)
demo.txContext = { tx, scriptCode, inputSatoshis, inputIndex }
const unlockFn = demo.spend(new SigHashPreimage(toHex(preimage)))
result = unlockFn.verify(demo.txContext)
expect(result.success, result.error).to.be.true

Something wrong around the following in contract.ts

const ContractClass = class Contract extends AbstractContract {
    constructor(...ctorParams: SupportedParamType[]) {
      super();
      if (ctorParams.length > 0 || Contract.abi.find(fn => (fn.type === 'constructor' && fn.params.length === 0))) {
        this.scriptedConstructor = Contract.abiCoder.encodeConstructorCall(this, Contract.asm, ...ctorParams);
      }
    }

test deployments in CI

Not for every commit, run in cron weekly.

Need a faucet address w/ funds always available.

Compile Error: stack should have at least 1 element(s) when execute OP_DROP, BUT without the OP

When I compile some code, got an error. it shows "stack should have at least 1 element(s) when execute OP_DROP", but there is not OP_DROP in the code.

contract MultiSignBug {
  public function unlock(bytes p0, bytes p1) {
    asm {
      OP_0
      OP_TOALTSTACK
      OP_IF
        OP_DUP
        OP_HASH160
        dd2d89bb9f64cbdf4139ff0e23c4813124af85e6
        OP_EQUALVERIFY
        OP_CHECKSIGVERIFY
        OP_FROMALTSTACK
        OP_1ADD
        OP_TOALTSTACK
      OP_ENDIF
      OP_IF
        OP_DUP
        OP_HASH160
        aef82c0ef3f0c1d867e12b64e9e8d2ebb983dc81
        OP_EQUALVERIFY
        OP_CHECKSIGVERIFY
        OP_FROMALTSTACK
        OP_1ADD
        OP_TOALTSTACK
      OP_ENDIF
      OP_2
      OP_FROMALTSTACK
      OP_GREATERTHANOREQUAL
    }
  }
}
Compiling contract /Users/lilong/Works/scrypt-sv/boilerplate/contracts/MultiSignBug.scrypt ...
scryptc: stack should have at least 1 element(s) when execute OP_DROP
CallStack (from HasCallStack):
  error, called at library/IR.hs:844:7 in scrypt-0.4.0-6NbrB0JZAjUF7YaB6RhLSB:IR
Error: Command failed: /Users/lilong/.vscode/extensions/bsv-scrypt.scrypt-0.7.1/compiler/scryptc/mac/scryptc compile --asm --ast --debug  -r -o "/Users/lilong/Works/scrypt-sv/boilerplate/deployments/fixture/autoGen" 
scryptc: stack should have at least 1 element(s) when execute OP_DROP
CallStack (from HasCallStack):
  error, called at library/IR.hs:844:7 in scrypt-0.4.0-6NbrB0JZAjUF7YaB6RhLSB:IR

    at checkExecSyncError (child_process.js:630:11)
    at Object.execSync (child_process.js:666:15)
    at Object.compile (/Users/lilong/Works/scrypt-sv/boilerplate/node_modules/scryptlib/dist/compilerWrapper.js:53:38)
    at compileContract (/Users/lilong/Works/scrypt-sv/boilerplate/node_modules/scryptlib/dist/utils.js:611:38)
    at compileContract (/Users/lilong/Works/scrypt-sv/boilerplate/helper.js:149:18)
    at compile_for (/Users/lilong/Works/scrypt-sv/boilerplate/watcher.js:12:7)
    at /Users/lilong/Works/scrypt-sv/boilerplate/watcher.js:44:9
    at Array.forEach (<anonymous>)
    at /Users/lilong/Works/scrypt-sv/boilerplate/watcher.js:43:22
    at /Users/lilong/Works/scrypt-sv/boilerplate/node_modules/watch/main.js:112:5 {
  status: 1,
  signal: null,
  output: [
    null,
    <Buffer >,
    <Buffer 73 63 72 79 70 74 63 3a 20 73 74 61 63 6b 20 73 68 6f 75 6c 64 20 68 61 76 65 20 61 74 20 6c 65 61 73 74 20 31 20 65 6c 65 6d 65 6e 74 28 73 29 20 77 ... 132 more bytes>
  ],
  pid: 32398,
  stdout: <Buffer >,
  stderr: <Buffer 73 63 72 79 70 74 63 3a 20 73 74 61 63 6b 20 73 68 6f 75 6c 64 20 68 61 76 65 20 61 74 20 6c 65 61 73 74 20 31 20 65 6c 65 6d 65 6e 74 28 73 29 20 77 ... 132 more bytes>
}

Incompatibility with sCrypt VSCode extension

All tests are running fine.

Using the context menu option "Compile to Bitcoin Script" fails though for some but not all of the example contracts.
The VSCode extension also lints these errors. For example in the demo contract:
image

Refactor: put in a function in TxUtil

Same code:
call it verifyContractByHash()

// validate the tx containing the contract
require(hash256(prevouts) == SigHash.hashPrevouts(preimage));
bytes contractTxId = TxUtil.getPrevoutTxid(prevouts, contractInputIndex);
// validate the contract raw tx
require(hash256(contractTx) == contractTxId);
// validate the contract, i.e., its locking script
int contractOutputIndex = TxUtil.getPrevoutOutputIdx(prevouts, contractInputIndex);
bytes contractScript = TxUtil.readOutput(contractTx, contractOutputIndex).script;
require(hash160(contractScript) == from);

require(hash256(prevouts) == SigHash.hashPrevouts(txPreimage));
// validate the tx containing the callee contract
bytes prevScriptTxId = TxUtil.getPrevoutTxid(prevouts, calleeContractInputIndex);
require(hash256(calleeContractTx) == prevScriptTxId);
// validate the callee contract, i.e., its locking script
int lockContractTxOutIndex = TxUtil.getPrevoutOutputIdx(prevouts, selfContractInputIndex);
bytes prevScriptCode = TxUtil.readOutput(calleeContractTx, lockContractTxOutIndex).script;
require(hash160(prevScriptCode) == this.calleeContractHash);

checkSig() in sCrypt

Basically, implement ECDSA verification.

Sample code:

contract ECDSA {
    int S;
    int N;
    bytes G;

    constructor() {
        this.S = 33;
        this.N = bin2num(0x414136d08c5ed2bf3ba048afe6dcaebafeffffffffffffffffffffffffffffff00);
        int Gx = bin2num(0x9817f8165b81f259d928ce2ddbfc9b02070b87ce9562a055acbbdcf97e66be7900);
        int Gy = bin2num(0xb8d410fb8fd0479c195485a648b417fda808110efcfba45d65c4a32677da3a4800);
        this.G = num2bin(Gx, this.S) + num2bin(Gy, this.S);
    }

    function little2BigEndian(bytes num) returns (bytes) {
        bytes res = 0x;
        // S: 64 + 1
        loop (33) {
            if (size(num) > 0) {
                // bytes [head, tail] = num @ 1;
                bytes head = num[0:1];
                res = head ++ res;
                num = num[1:size(num)];
            }
        }
        return res;
    }

    function normalize(int k, int modulus) returns (int) {
        k = k % modulus;
        if (k < 0) {
            k = k + modulus;
        }
        return k;
    }
  
    // n must be positive
    function inverse(int a, int n) returns (int) {
        a = this.normalize(a, n);

        int t = 0;
        int newt = 1;
        int r = n;
        int newr = a;

        int quotient = 0;
        int tmp = 0;

        loop (386) {
            if (newr != 0) {
                quotient = r / newr;
                
                tmp = newt;
                newt = t - quotient * newt;
                t = tmp;
                
                tmp = newr;
                newr = r - quotient * newr;
                r = tmp;
            }
        }

        //if (r > 1)
        //    return 0; // 'a is not invertible'
        
        if (t < 0)
            t = t + n;
        
        return t;
    }

    function doublePoint(bytes p) returns(bytes) {
        int A = 0;
        int P = bin2num(0x2ffcfffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff00);
        
        // bin [pxb, pyb] = p @ S;
        bytes pxb = p[0:this.S];
        bytes pyb = p[this.S:size(p)];
        
        int px = bin2num(pxb);
        int py = bin2num(pyb);

        bytes ret = 0x;

        // special case: infinity point
        if (px == 0 && py == 0) {
            ret = num2bin(0, this.S) ++ num2bin(0, this.S);
        } else {
            int lambda = (3 * px * px + A) * this.inverse(2 * py, P);

            int rx = this.normalize(lambda * lambda - 2 * px, P);
            int ry = this.normalize(lambda * (px - rx) - py, P);

            ret = num2bin(rx, this.S) ++ num2bin(ry, this.S);
        }

        return ret;
    }

    function addPoint(bytes p, bytes q) returns (bytes) {
        int P = bin2num(0x2ffcfffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff00);

        // bytes [pxb, pyb] = p @ S;
        // bytes [qxb, qyb] = q @ S;
        bytes pxb = p[0:this.S];
        bytes pyb = p[this.S:size(p)];
        bytes qxb = q[0:this.S];
        bytes qyb = q[this.S:size(q)];

        int px = bin2num(pxb);
        int py = bin2num(pyb);

        int qx = bin2num(qxb);
        int qy = bin2num(qyb);

        bytes ret = 0x;

        // special case: infinity point
        if (px == 0 && py == 0) {
            ret = q;
        } else if (qx == 0 && qy == 0) {
            ret = p;
        } else if (px == qx && py == qy) {
            // same point
            ret = this.doublePoint(p);
        } else {
            int xdiff = qx - px;
            int lambda = (qy - py) * this.inverse(xdiff, P);

            int rx = this.normalize(lambda * lambda - px - qx, P);
            int ry = this.normalize(lambda * (px - rx) - py, P);

            ret = num2bin(rx, this.S) ++ num2bin(ry, this.S);
        }

        return ret;
    }

    function scalePoint(bytes p, int m) returns (bytes) {
        bytes n = p;
        bytes q = num2bin(0, this.S) ++ num2bin(0, this.S);

        bytes mb = this.little2BigEndian(num2bin(m, this.S));
        //bytes mb = num2bin(m, this.S);

        //bytes res = 0x;
        bytes mask = this.little2BigEndian(num2bin(1, this.S));
        bytes zero = this.little2BigEndian(num2bin(0, this.S));
        //bytes mask = num2bin(1, this.S);
        //bytes zero = num2bin(0, this.S);
        int i = 0;

        // lowest bit to highest
        loop (256) {
            if ((mb & (mask << i)) != zero) {
            //res = res . 0x11;
            q = this.addPoint(q, n);
            //} else {
            //res = res . 0x00;
            }

            n = this.doublePoint(n);
            i = i + 1;
        }

        return q;
    }

    function sign(bytes h, bytes privKey) returns (Sig) {
        // int k = bin2num(0x2e20721ffd20aa0f65ec50b94b694c9d5b29e53625c271eefc498fb5290e415e00);
        int inverseK = bin2num(0x0ac407f0e4bd44bfc207355a778b046225a7068fc59ee7eda43ad905aadbffc800);
        int r = bin2num(0x6c266b30e6a1319c66dc401e5bd6b432ba49688eecd118297041da8074ce081000);
        // big endian
        bytes rbe = 0x001008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266c;
        int s = inverseK * (bin2num(h) + r * bin2num(privKey));
        s = this.normalize(s, this.N);
        // require(s != 0);
        bytes rb = 0x30460221 ++ rbe ++ 0x0221++ this.little2BigEndian(num2bin(s, this.S)) ++ 0x41;
        return Sig(rb);
    }

    // 1 0x0d 1 0x16 1 0x0e
    function verify() returns (bool) {
        int sigR = bin2num(0xf203ca6e661e72de80ad3e0791108b007dbf6b4b1f8103ec17162b63d864c52400);
        int sigS = bin2num(0x296ada51bac4b0791fcad3c335e5966e5d8361a51efff9bd01f373357f5c8b6300);
        int hash = bin2num(0x793ff39de7e1dce2d853e24256099d25fa1b1598ee24069f24511d7a2deafe6c00);

        require(sigR >= 1 && sigR < this.N && sigS >= 1 && sigS < this.N);

        int invS = this.inverse(sigS, this.N);
        int u1 = this.normalize(hash * invS, this.N);
        int u2 = this.normalize(sigR * invS, this.N);
        //verify 26 == u1;
        //verify 2 == u2;

        bytes U1 = this.scalePoint(this.G, u1);
        //bytes [u1xb, u1yb] = U1 @ this.S;
        //verify 2 == bin2num(u1xb);
        //verify 21 == bin2num(u1yb);

        int pubKeyx = bin2num(0x8203ec8ebef8c45d026fa17506deae86810233793cf030984a60e78a5fdf79ba00);
        int pubKeyy = bin2num(0xfc76213ae2308924dd0eef035054d205dbca9b1e97413f2b748ff16a3fe8d8c400);
        bytes pubKey = num2bin(pubKeyx, this.S) ++ num2bin(pubKeyy, this.S);
        bytes U2 = this.scalePoint(pubKey, u2);
        //bytes [u2xb, u2yb] = U2 @ this.S;
        //verify 8 == bin2num(u2xb);
        //verify 17 == bin2num(u2yb);

        bytes res = this.addPoint(U1, U2);
        // bytes [resXb, resYb] = res @ this.S;
        bytes resXb = res[0:this.S];
        bytes resYb = res[this.S:size(res)];
        int resX = bin2num(resXb);

        //verify 13 == bin2num(resXb);
        //verify 25 == bin2num(resYb);

        return (resX == sigR);
    }

    public function unlock(Sig y) {
        // require(this.verify());
        require(y == this.sign(0x793ff39de7e1dce2d853e24256099d25fa1b1598ee24069f24511d7a2deafe6c00, 
                               0x97dfd76851bf465e8f715593b217714858bbe9570ff3bd5e33840a34e20ff02600));
    }
}

Some test code:

let bsv = require('bsv')
let BN = bsv.crypto.BN
let fs = require('fs')
let readline = require('readline-sync');
let assert = require('assert')

// let n = BN.fromNumber(5)
// let m = BN.fromNumber(6)
// console.log(n.add(m).toString())

// let str = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'
// let buf = Buffer.from(str, 'hex')
// let n = BN.fromBuffer(buf)
// let a = new BN('3847f126769a6c65d281d925f9ff990f431d19c8c314f9180def0ab95b24f062', 'hex')
// // console.log(a.toString('hex'))
// let inv = a.invm(n)
// console.log(inv.toString('hex'))
// let res = a.mul(inv).umod(n)
// console.log(res.toString())

let scripts = []
const PREFIX = "0x"
const SUFFIX = "00"
function hex2ScriptNum(hex) {
    let num = new BN(hex, 'hex')
    let buf = num.toBuffer()
    // PUSHDATA0 encoding
    return (buf.length + 1) + " " + PREFIX + buf.toString('hex').match(/.{2}/g).reverse().join("") + SUFFIX
}

// var privateKey = bsv.PrivateKey.fromRandom()
var privateKey = bsv.PrivateKey.fromWIF('KxXQCRaJ4Vos3aDx4dmff6B2Y5P1UaU3VPNvDsM1myzfGnwWZKvM')
// console.log(privateKey.bn.toString('hex'))
var publicKey = bsv.PublicKey.fromPrivateKey(privateKey)
console.log("public key x: " + publicKey.point.getX().toString('hex'))
scripts.push(hex2ScriptNum(publicKey.point.getX().toString('hex')))
console.log("public key y: " + publicKey.point.getY().toString('hex'))
scripts.push(hex2ScriptNum(publicKey.point.getY().toString('hex')))

//var data = 'this is my data that i want to sign'
//var data = 'this is the data that i want to sign'
var data = 'this is the data that i wanna sign'
// var data = readline.question("What is the message you want to sign?\n");
var hash = bsv.crypto.Hash.sha256(Buffer.from(data))
console.log("message hash: " + hash.toString('hex'))
scripts.push(hex2ScriptNum(hash.toString('hex')))
var sig = bsv.crypto.ECDSA.sign(hash, privateKey)
console.log("signature r: " + sig.r.toString('hex'))
console.log("signature s:" + sig.s.toString('hex'))
scripts.push(hex2ScriptNum(sig.r.toString('hex')))
scripts.push(hex2ScriptNum(sig.s.toString('hex')))

const fileName = "unlock.asm"
fs.writeFileSync(fileName, scripts.join(" "))
console.log("Unlock script written to " + fileName)

var verified = bsv.crypto.ECDSA.verify(hash, sig, publicKey)
console.log(verified)

// // hash: 0x793ff39de7e1dce2d853e24256099d25fa1b1598ee24069f24511d7a2deafe6c00
// reverseEndian('6cfeea2d7a1d51249f0624ee98151bfa259d095642e253d8e2dce1e79df33f79')
// // r: 0xf203ca6e661e72de80ad3e0791108b007dbf6b4b1f8103ec17162b63d864c52400
// reverseEndian('24c564d8632b1617ec03811f4b6bbf7d008b1091073ead80de721e666eca03f2')
// // s: 0x296ada51bac4b0791fcad3c335e5966e5d8361a51efff9bd01f373357f5c8b6300
// reverseEndian('638b5c7f3573f301bdf9ff1ea561835d6e96e535c3d3ca1f79b0c4ba51da6a29')
// // pubKey.x: 0x8203ec8ebef8c45d026fa17506deae86810233793cf030984a60e78a5fdf79ba00
// reverseEndian('ba79df5f8ae7604a9830f03c7933028186aede0675a16f025dc4f8be8eec0382')
// // pubKey.y: 0xfc76213ae2308924dd0eef035054d205dbca9b1e97413f2b748ff16a3fe8d8c400
// reverseEndian('c4d8e83f6af18f742b3f41971e9bcadb05d2545003ef0edd248930e23a2176fc')

// // curve
// // P: 0x2ffcfffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff00
// reverseEndian('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F')
// // N: 0x414136d08c5ed2bf3ba048afe6dcaebafeffffffffffffffffffffffffffffff00
// reverseEndian('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141')
// // G
// var G = bsv.crypto.Point.getG()
// console.log(G.getX().toString('hex'))
// // G.x: 0x9817f8165b81f259d928ce2ddbfc9b02070b87ce9562a055acbbdcf97e66be7900
// reverseEndian('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798')
// // G.y: 0xb8d410fb8fd0479c195485a648b417fda808110efcfba45d65c4a32677da3a4800
// console.log(G.getY().toString('hex'))
// reverseEndian('483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8')

rewrite all stateful contracts with propagateState()

contract Counter {
  @state
  public int count;

  public function get(int retVal, SigHashPreimage txPreimage) {
    require(this.count == retVal);
    require(this.propagateState(txPreimage, SigHash.value(txPreimage)));
  }

  public function inc(SigHashPreimage txPreimage) {
    this.count += 1;
    require(this.propagateState(txPreimage, SigHash.value(txPreimage)));
  }

  public function set(int _count, SigHashPreimage txPreimage) {
    this.count = _count;
    require(this.propagateState(txPreimage, SigHash.value(txPreimage)));
  }

  function propagateState(SigHashPreimage txPreimage, int value) : bool {
    require(Tx.checkPreimage(txPreimage));
    bytes outputScript = this.getStateScript();
    bytes output = Utils.buildOutput(outputScript, value);
    return hash256(output) == SigHash.hashOutputs(txPreimage);
  }
}

All deployments fail

All deployments start failing all of a sudden. Could be due to our recent changes or whatonchain API.

node deployments/demo.js 
Failed on testnet
Error: undefined - For more information please see: https://bsv.io/api/lib/transaction#serialization-check

Make this a "Template Repo"

One setting and this can be "template repo" which people can clone but will not be a fork and will not have any git history.

npm run watch doesn't generate _desc.json files

Hi,
i had to change function compile_for in watcher.js.

const path = require('path')
...
      clean_description_file(fileName)
      const out = path.join(__dirname, 'out')
      compileContract(fileName, {desc: true, out: out });

now [contract]_debug_desc.json are correctly generated in out directory.

Update Rabin Signature

  1. Separate TestRabinSignature into its own file.
  2. Fix rest of test commented
  3. Update BinaryOption & WitnessBinaryOption
  4. new RabinPubKey() fails: TypeError: RabinPubKey is not a constructor

See branch rabin

refactor: renaming EC

Name is confusing and not easy to locate files. Let us change:

  • rename EC -> ECVerify and ec.scrypt -> ecVerify.scrypt
  • rename SECP256K1 -> EC and scep256k1.scrypt -> ec.scrypt
  • make UniversalSigHash compile

remove tx_

ensure each scrypttest gets a fresh copy of tx

Tx.checkPreimageOpt raise SCRIPT_ERR_SIG_DER_INVALID_FORMAT exception

The exception was randomly raise.

reproduce steps:

  1. fix tokenUtxo.scrypt, replace all Tx.checkPreimage to Tx.checkPreimageOpt

  2. run test tokenUtxo.scrypttest.js

% npm run single-test tests/js/tokenUtxo.scrypttest.js

> [email protected] single-test /xxx/boilerplate-master
> mocha -r ts-node/register --reporter spec --timeout 120000 "tests/js/tokenUtxo.scrypttest.js"



  Test sCrypt contract UTXO Token In Javascript
Compiling contract /xxx/boilerplate-master/contracts/tokenUtxo.scrypt ...
    1) should succeed when one token is split into two
    2) should succeed when two tokens are merged
    ✓ should succeed when one token UTXO is burnt (127ms)


  1 passing (6s)
  2 failing

  1) Test sCrypt contract UTXO Token In Javascript
       should succeed when one token is split into two:

      SCRIPT_ERR_SIG_DER_INVALID_FORMAT
      + expected - actual

      -false
      +true
      
      at Context.<anonymous> (tests/js/tokenUtxo.scrypttest.js:72:47)
      at processImmediate (internal/timers.js:456:21)

  2) Test sCrypt contract UTXO Token In Javascript
       should succeed when two tokens are merged:

      SCRIPT_ERR_SIG_DER_INVALID_FORMAT
      + expected - actual

      -false
      +true
      
      at Context.<anonymous> (tests/js/tokenUtxo.scrypttest.js:155:47)
      at processImmediate (internal/timers.js:456:21)

[solved] privateKey.js opensslErrorStack OSX M1

ISSUE at OSX M1:

at Module._compile (node:internal/modules/cjs/loader:1097:14) {
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'

Solution:

export NODE_OPTIONS=--openssl-legacy-provider

Support BLS12-381

https://hackmd.io/@benjaminion/bls12-381
zcash/zcash#2502

BLS12 in 5 slides: https://docs.google.com/presentation/d/1uN-ziUVXP1xtxEyKc5piHcVnOqcrTk26WIk-fzkbOMs/edit#slide=id.p

However, neither RSK nor Ethereum have activated native support for this curve. https://medium.com/iovlabs-innovation-stories/choosing-the-right-curve-bf183d477a

Since neither EIP-2537, nor EVM384 precompiles have been implemented on mainnet
https://ethresear.ch/t/do-not-add-bls12-precompile-implement-pasta-curves-w-o-trusted-setup-instead/12808

For platform-agnostic applications, the choice requires a tradeoff between performance (BN254) and security (BLS12-381). We recommend choosing BLS12-381 as it is more secure, still fast enough to be practical, but slower than BN254. https://docs.gnark.consensys.net/en/latest/Concepts/schemes_curves/#bn254-and-bls12-381-curves

Reference implementation

Go impl in Eth https://github.com/ethereum/go-ethereum/tree/master/crypto/bls12381

Circom impl by 0xparc: https://github.com/yi-sun/circom-pairing/tree/master/circuits
See section Adapting to other elliptic curves, adapted from https://github.com/paulmillr/noble-bls12-381

Test

bug: generate private whenever a test is run

Right click and run any test like demo.scryptttest.js

Start running sCrypt test in /Users/xhliu/projects/scrypt/public/boilerplate/tests/js/demo.scrypttest.js:

> [email protected] single-test /Users/xhliu/projects/scrypt/public/boilerplate
> mocha -r ts-node/register --reporter spec --timeout 120000 "/Users/xhliu/projects/scrypt/public/boilerplate/tests/js/demo.scrypttest.js" "--scryptc=/Users/xhliu/.vscode/extensions/bsv-scrypt.scrypt-1.3.0/compiler/scryptc/mac/scryptc" "--debugUri"

Missing private key, generating a new one ...
Private key generated: 'cRgZeLWQJxGyRQUgpy7kQCWpmFQNQoZjWNdd33ZjmRknV77zjEX9'
You can fund its address 'mgr1vrAuPTLiFhao4QnAdvNzx5PUB6x6o7' from some faucet and use it to complete the test
Example faucets are https://faucet.bitcoincloud.net and https://testnet.satoshisvision.network
running sCrypt test in /Users/xhliu/projects/scrypt/public/boilerplate/tests/js/demo.scrypttest.js:  successfully 

diff --git a/helper.js b/helper.js
index 5c1367c..2f434a7 100644
--- a/helper.js
+++ b/helper.js
@@ -10,7 +10,7 @@ const {
getPreimage,
toHex
} = require('scryptlib')
-const { privateKey } = require('./privateKey');
+// const { privateKey } = require('./privateKey');
const MSB_THRESHOLD = 0x7e;

Expected arguments (byte[]) but got (bytes)

Constructor of contract ... expected arguments (byte[]) but got (bytes) - This happens when entering bytes strings (b'...') as input for constructorParams in launch.json and requiring a bytes string in the contract like this:

contract Test {
  bytes test;

  ...
}

When wrapped in Sha256 for example, it works fine.

Test fails on Windows

Every time i try to test the Demo contract i get the following error

Start running scrypt test in c:\Users\Juan Finol\Desktop\boilerplate-master\tests\js\demo.scrypttest.js:

 [email protected] single-test c:\Users\Juan Finol\Desktop\boilerplate-master
 mocha -r ts-node/register --reporter spec --timeout 120000 "c:\Users\Juan Finol\Desktop\boilerplate-master\tests\js\demo.scrypttest.js"

'mocha' is not recognized as an internal or external command,
operable program or batch file.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] single-test: `mocha -r ts-node/register --reporter spec --timeout 120000 "c:\Users\Juan Finol\Desktop\boilerplate-master\tests\js\demo.scrypttest.js"`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] single-test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Juan Finol\AppData\Roaming\npm-cache\_logs\2020-08-22T01_55_29_109Z-debug.log

XOR puzzle fails sometimes

  1. Test sCrypt contract HashPuzzle In Javascript
    "before all" hook for "check should succeed when correct data provided":
    Error: can't get type from undefined, should have even length

An ASM debug exception on OP_EQUALVERIFY using vscode

I got debug exception like screenshot using vscode extension 0.7.1

截屏2021-04-04 12 27 54

in the mainstack, we have two same item.

Contract Code

SimpleP2PKH.scrypt >>>>>>>>>>

contract SimpleP2PKH {
  public function unlock(bytes p0, bytes p1) {
    asm {
      OP_DUP
OP_HASH160
10ca715f0eb9c5a89e6566aa611fadb853de6c53
OP_EQUALVERIFY
OP_CHECKSIG
    }
  }
}
  
<<<<<<<<<< SimpleP2PKH.scrypt  

Debug launch.json

launche.json >>>>>>>>>>

{
  "type": "scrypt",
  "request": "launch",
  "name": "Debug SimpleP2PKH",
  "program": "${workspaceFolder}/contracts/SimpleP2PKH.scrypt",
  "constructorArgs": [
  ],
  "pubFunc": "unlock",
  "pubFuncArgs": [
    "b'30440220503a1d61d769d11793cd317c673d288516c7cce8034280b72ca76a24f2efab0302200cbc5717ea1db1856c84b1ac5ffc06f4248413aa1782642061d196249739bc8641'", "b'026f99c6e88e5f351691a5241f704879b01e082fdf2653bd9559498b61c516235b'"
  ]
}
  
<<<<<<<<<< launche.json

compile error

I got an error on compiling the code when I edit Line: 29, the error message is jumping to Line 125

https://github.com/baryon/boilerplate/blob/b8df7cea13feea18d743f0be7b5abd963cfac7cd/contracts/improvedTokenUtxo.scrypt

Compiling contract /Users/xxx/scrypt-sv/boilerplate/contracts/improvedTokenUtxo.scrypt ...
Contract /Users/xxx/scrypt-sv/boilerplate/contracts/improvedTokenUtxo.scrypt compiling failed with errors:
[
  {
    type: 'SyntaxError',
    filePath: '/Users/xxx/scrypt-sv/boilerplate/contracts/improvedTokenUtxo.scrypt',
    position: { line: 125, column: 13 },
    message: 'keyword "public" cannot be an identifier',
    unexpected: '',
    expecting: ''
  }
]
[
  {
    type: 'SyntaxError',
    filePath: '/Users/xxx/scrypt-sv/boilerplate/contracts/improvedTokenUtxo.scrypt',
    position: { line: 125, column: 13 },
    message: 'keyword "public" cannot be an identifier',
    unexpected: '',
    expecting: ''
  }
]

Env:

    "scryptc": "^0.2.2",
    "scryptlib": "^0.2.1",

All tests fail for various reasons on Windows

running npm test fails with various errors:

> git clone [email protected]:scrypt-sv/boilerplate.git

Cloning into 'boilerplate'...
remote: Enumerating objects: 45, done.
remote: Counting objects: 100% (45/45), done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 451 (delta 22), reused 28 (delta 11), pack-reused 406 eceiving objects:  97% (438/451)
Receiving objects: 100% (451/451), 208.40 KiB | 833.00 KiB/s, done.
Resolving deltas: 100% (253/253), done.


> cd boilerplate

> npm install

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\mocha\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

added 603 packages from 871 contributors and audited 609 packages in 22.948s

18 packages are looking for funding
  run `npm fund` for details

found 14 low severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details


> npm test

> [email protected] test C:\[...]\boilerplate
> mocha -r ts-node/register tests/**/*scrypttest.*  --reporter spec --timeout 120000

  Test sCrypt contract Ackermann In Javascript
    1) "before all" hook for "should return true"

  Test sCrypt contract Counter In Javascript
    2) "before all" hook for "should succeed when pushing right preimage & amount"

[...]

  0 passing (15s)
  12 failing

  1) Test sCrypt contract Ackermann In Javascript
       "before all" hook for "should return true":
     Error: Compilation error: ENOENT
      at compile (node_modules\scrypttest\dist\local.js:147:15)
      at buildContractClass (node_modules\scrypttest\dist\local.js:59:17)
      at Context.<anonymous> (tests\js\ackermann.scrypttest.js:9:23)
      at processImmediate (internal/timers.js:439:21)

  2) Test sCrypt contract Counter In Javascript
       "before all" hook for "should succeed when pushing right preimage & amount":
     Error: Compilation error: Error: Compilation fails: Error:
Syntax error: C:\[...]\boilerplate\contracts\advancedCounter.scrypt:1:8:
  |
1 | import "util.scrypt";
  |        ^
File not found: util.scrypt

      at compile (node_modules\scrypttest\dist\local.js:147:15)
      at buildContractClass (node_modules\scrypttest\dist\local.js:59:17)
      at Context.<anonymous> (tests\js\advancedCounter.scrypttest.js:30:21)
      at processImmediate (internal/timers.js:439:21)

[...]

npm ERR! Test failed.  See above for more details.


> npm --version

6.13.4

Some notes:

  • util.scrypt is there, but also the VSCode plugin complains that "Imported file util.scrypt does not existscrypt"
  • Commenting out the catch/throw block in node_modules\scrypttest\dist\local.js:147:15 shows that all the compilation errors are like this Error: ENOENT: no such file or directory, open 'p2pkh_asm.json'

I'm new to VSCode, npm, and sCrypt, so I'm out of my league here. My guess would be that some path is not set correctly somewhere.

Perhaps running windows is the problem? I expected VSCode to only work on Windows, but apparently it should work on Linux too, which is my normal development environment.

refactor to optimize pairing

FQ12 acc = BN256.FQ12One;
a0 = BN256.makeAffineCurvePoint(a0);
a2 = BN256.makeAffineCurvePoint(a2);
a3 = BN256.makeAffineCurvePoint(a3);
if (!BN256.isInfCurvePoint(a0) && !BN256.isInfTwistPoint(b0)) {
acc = BN256.mulFQ12(acc, miller(b0, a0));
}
acc = BN256.mulFQ12(acc, millerBetaAlpha);

Optimize
FQ12 acc = millerBetaAlpha;

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.