reach-sh / reach-lang Goto Github PK
View Code? Open in Web Editor NEWReach: The Safest and Smartest DApp Programming Language
Home Page: https://www.reach.sh
License: Apache License 2.0
Reach: The Safest and Smartest DApp Programming Language
Home Page: https://www.reach.sh
License: Apache License 2.0
Attempted to make a reach program, but it had a parse issue.
Here is the error:
Verifying knowledge assertions
Verifying for generic connector
Verifying when ALL participants are honest
Verification failed:
when ALL participants are honest
of theorem: while invariant after loop
at ./index.rsh:118:3:invariant
reachc: The compiler has encountered an internal error:
parseVal: Array(Object({"date": UInt, "inventoryUnit": UInt, "inventoryValue": UInt, "stateName": UInt, "supplyName": UInt, "transitions": Array(UInt, 10), "transitionsLength": UInt}), 10) List [Atom "_",Atom "as-array",Atom "k!38"]
This error indicates a problem with the Reach compiler, not your program. Please report this error, along with the pertinent program, to the Reach team as soon as possible so we can fix it.
Open an issue at: https://github.com/reach-sh/reach-lang/issues
CallStack (from HasCallStack):
error, called at src/Reach/Util.hs:73:3 in reach-0.1.2-DAFksisXDyRKXmySyEXCbN:Reach.Util
impossible, called at src/Reach/Verify/SMT.hs:467:10 in reach-0.1.2-DAFksisXDyRKXmySyEXCbN:Reach.Verify.SMT
Here is the gist of the code that generated the issue:
https://gist.github.com/jboetticher/33dffa61b5904a887421ab86dd7f3dd3
See index.rsh.
I believe there is no reason to pass ticketPrice
to interact.shouldBuyTicket
.
index.mjs
does not use it: shouldBuyTicket : () => Math.random() < 0.5
Using Reach with the following code:
'reach 0.1'
'use strict'
const IAdministrator = {
getNewEntry: Fun([],Address),
}
const IRegistryView = {
last: UInt
}
export const main = Reach.App({
deployMode: "constructor"
},
[ Participant('Administrator', IAdministrator),
View('RegistryView', IRegistryView) ],
(Admin, RegistryView) => {
Admin.publish();
const registry = new Set()
const isRunning = parallelReduce(true)
.invariant(balance () == 0) // No funds movement, should validate always
.while(isRunning)
.case(
Admin,
/* publish_expr */
(() => ({
msg: declassify(interact.getNewEntry())
})),
/* pay_expr */
((_) => 0),
/* consensus_expr */
((addr) => {
registry.insert(addr);
return isRunning;
})
)
commit();
})
yields:
hernandp@LAPTOP-QJTRSF6V:~/src/reach-scratchpad/03-registry$ ./reach compile registry.rsh
Verifying knowledge assertions
Verifying for generic connector
Verifying when ALL participants are honest
Verifying when NO participants are honest
Verifying when ONLY "Administrator" is honest
Checked 12 theorems; No failures!
reachc: The compiler has encountered an internal error:
sol view defn
This error indicates a problem with the Reach compiler, not your program. Please report this error, along with the pertinent program, to the Reach team as soon as possible so we can fix it.
Open an issue at: https://github.com/reach-sh/reach-lang/issues
CallStack (from HasCallStack):
error, called at src/Reach/Util.hs:67:3 in reach-0.1.2-1JzW2Z5sBxAzanGaqepiq:Reach.Util
impossible, called at src/Reach/Connector/ETH_Solidity.hs:1223:36 in reach-0.1.2-1JzW2Z5sBxAzanGaqepiq:Reach.Connector.ETH_Solidity
Platform information:
Linux LAPTOP-QJTRSF6V 5.4.72-microsoft-standard-WSL2 #1 SMP Wed Oct 28 23:40:43 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
reach version
output:
reach 0.1
Thanks.
Starting with Tutorial 5, frontends spread stdlib.hasRandom
into Player
objects:
const Player = (Who) => ({
...stdlib.hasRandom,
getHand: async () => {const hand = Math.floor(Math.random() * 3);
etc.
});
The inclusion of stdlib.hasRandom
has nothing to do with the subsequent use of Math.random
and Math.floor
as some readers might mistakenly conclude. The only reason I can see to include stdlib.hasRandom
in frontend Player
objects (in this case) is to make stdlib.hasRandom.random()
available to makeCommitment
in the backend. If I am correct (never a sure thing) then this is like a patient bringing a stethoscope to a doctor's visit: the Dr should already have all needed equipment, and makeCommitment
should take care of internal processing needs without the frontend supplying stdlib.hasRandom.random()
.
I admit, there may be other reasons for frontends to supply stdlib.hasRandom
in the tutorials that I don't understand. If so, apologies!
This was something jbo in the Discord server encountered
while defining functions in .rsh code, having return statements inside if block doesn't work as expected
Here is the contract I wrote the reproduce the error
// BACKEND (.rsh)
'reach 0.1';
export const main = Reach.App(() => {
const Alice = Participant('Alice', {
log: Fun(true, Null)
});
deploy();
Anybody.publish();
const state = {
roll: 12
};
const cmd = {
skip: true
};
const p1 = 1;
function attempt(localGameState, player, buildCmd) {
if (buildCmd.skip) {
return {
winner: 2,
roll: localGameState.roll,
turn: player
};
}
return {
winner: buildCmd.skip ? 1 : 0,
roll: 0,
turn: 0
};
}
const result = attempt(state, p1, cmd)
Alice.interact.log(result);
commit();
exit();
});
// FRONTEND (.mjs)
import { loadStdlib } from '@reach-sh/stdlib';
import * as backend from './build/index.main.mjs';
(async () => {
const stdlib = await loadStdlib();
const startingBalance = stdlib.parseCurrency(100);
const alice = await stdlib.newTestAccount(startingBalance);
const ctcAlice = alice.deploy(backend);
await backend.Alice(ctcAlice, {
log: (x) => {
console.log("{");
for (let obj of Object.keys(x)) {
console.log(`\t${obj}: ${stdlib.bigNumberToNumber(x[obj])}`);
}
console.log("}");
}
});
})();
// Expected result
/*
{
roll: 12
turn: 1
winner: 2
}
*/
// Actual result
/*
{
roll: 0
turn: 0
winner: 1
}
*/
Reach init allows a base .rsh file. Reach currently uses Participant by default although this is not present in the current updated .rsh file.
$ ./reach compile
Traceback (most recent call last):
File "/usr/bin/docker-compose", line 11, in <module>
load_entry_point('docker-compose==1.25.0', 'console_scripts', 'docker-compose')()
File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 72, in main
command()
File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 125, in perform_command
project = project_from_options('.', options)
File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 53, in project_from_options
return get_project(
File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 156, in get_project
execution_context_labels(config_details, environment_file),
File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 163, in execution_context_labels
'{0}={1}'.format(LABEL_CONFIG_FILES, config_files_label(config_details)),
File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 172, in config_files_label
return ",".join(
File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 173, in <genexpr>
map(str, (os.path.normpath(c.filename) for c in config_details.config_files)))
File "/usr/lib/python3.8/posixpath.py", line 336, in normpath
path = os.fspath(path)
TypeError: expected str, bytes or os.PathLike object, not NoneType
It's reach from later master
branch.
Received the following error after running reach compile
. Error prevents the file from being actually compiled, but may be a red-herring.
$:: REACH_CONNECTOR_MODE=ALGO reach compile index.rsh
reachc: The compiler has encountered an internal error:
6 lookup_let v109 not in v28, v30, v34, v35, v37, v76, v77, v79, v92, v93, v95, v96, v97, v98, v99, v100, v101, v105, v126, v679, v680
This error indicates a problem with the Reach compiler, not your program. Please report this error, along with the pertinent program, to the Reach team as soon as possible so we can fix it.
Open an issue at: https://github.com/reach-sh/reach-lang/issues
CallStack (from HasCallStack):
error, called at src/Reach/Util.hs:66:3 in reach-0.1.2-1JzW2Z5sBxAzanGaqepiq:Reach.Util
impossible, called at src/Reach/Connector/ALGO.hs:366:7 in reach-0.1.2-1JzW2Z5sBxAzanGaqepiq:Reach.Connector.ALGO
Verifying knowledge assertions
Verifying for generic connector
Verifying when ALL participants are honest
Verifying when NO participants are honest
Verifying when ONLY "Arbitrator" is honest
Verifying when ONLY "Contractor" is honest
Verifying when ONLY "Primary" is honest
Checked 123 theorems; No failures!
I commented the hell out of the code until it both reliably compiled and threw the error. Culprit was this conditional:
// Payouts: pay contractor if verified; else pay seller
const arbitratorFee = balance() / 50;
const bulk = balance() - arbitratorFee;
// Error caused by conditional statement below
Anybody.publish();
if (review == STATUS.VERIFIED) {
transfer(bulk).to(Contractor);
commit();
} else {
transfer(bulk).to(Primary);
commit();
}
index.rsh
file contains only one line (a closeTo
) below the errant conditional.Anybody
with race( ... )
arbitratorFee
const inside the conditional scopepublish
statement into the conditional scopeParticipant
to do the publishingSTATUS.VERIFIED
is a reference to the following, also defined in index.rsh
(above the App export):const STATUS = {
OPEN: 1,
INPROGRESS: 2,
REVIEW: 3,
VERIFIED: 4,
CANCELED: 5,
};
fork
statementv15.3.0
20.10.6
^0.1.2-rc.56
Hope this helps: I will keep a revision of the error-generating code around, just in case. Otherwise, please close or redirect this issue as needed. Cheers!
While assisting a community member. We witnessed this error.
312 | const txn5 = await (ctc.sendrecv(8, 1, stdlib.checkedBigNumberify('./index.rsh:394:15:dot', stdlib.UInt_max, 9), [ctc6, ctc0, ctc6, ctc6, ctc0, ctc0, ctc0, ctc8, ctc10, ctc0, ctc3], [v24, v25, v32, v39, v173, v175, v177, v178, v197, v322, v221], [stdlib.checkedBigNumberify('./index.rsh:decimal', stdlib.UInt_max, 0), []], [ctc3], true, true, false, (async (txn5) => {
| ^ 313 | const sim_r = { txns: [], mapRefs: [], mapsPrev: [], mapsNext: [] };
314 |
315 | sim_r.prevSt = stdlib.digest(ctc11, [stdlib.checkedBigNumberify('./index.rsh:394:15:dot', stdlib.UInt_max, 8), v24, v25, v32, v39, v173, v175, v177, v178, v197, v322]);
reach scaffold
generates a docker-compose.yml
file that contains inconsistencies regarding naming and ordering conventions that had been established prior to the addition of Conflux. Whether you stick to the old conventions or change to new ones, I recommend that you choose and follow your own conventions in order to help developers understand this file quickly. Here are examples:
Current Convention: name-devnet
.
Examples: ethereum-devnet
and algorand-devnet
.
Non-adherence: devnet-cfx
.
Current Convention: List live
first and then dockerized
.
Examples:
reach-app-seller-and-buyer-ETH-live
reach-app-seller-and-buyer-ETH-test-dockerized-geth
reach-app-seller-and-buyer-ALGO-live
reach-app-seller-and-buyer-ALGO-test-dockerized-algod
Non-adherence:
reach-app-seller-and-buyer-CFX-devnet
reach-app-seller-and-buyer-CFX-live
Current Convention: Indicate devnet
with test-dockerized
.
Examples:
reach-app-seller-and-buyer-ETH-test-dockerized-geth
reach-app-seller-and-buyer-ALGO-test-dockerized-algod
Non-adherence: reach-app-seller-and-buyer-CFX-devnet
.
Current Convention: Service order is Ethereum, Algorand.
Example:
ethereum-devnet:
image: reachsh/ethereum-devnet:0.1
algorand-devnet:
image: reachsh/algorand-devnet:0.1
reach-app-seller-and-buyer-ETH-live:
...
reach-app-seller-and-buyer-ALGO-live:
...
Non-adherence: The Conflux entries are inconsistent. The image entry appears before ethereum and algorand. The environment entry appears after ethereum and algorand.
Description
Page Link
Search String
Issue
Suggestion
const UserEntryType = Object({
address: Address,
returnedValue: UInt,
timestamp: UInt
});
gives:
reachc: The compiler has encountered an internal error:
solc failed:
STDOUT:
STDERR:
Error: Expected identifier but got 'address'
--> /tmp/reachc-sol-59cc096600b49f45/compiled.sol:91:19:
|
91 | address payable address;
| ^^^^^^^
whereas changing the key to anything else like:
const UserEntryType = Object({
add: Address,
returnedValue: UInt,
timestamp: UInt
});
works fine
Do you have in program an outside-of-the-network testing suite or something related to testing?
// index.rsh
'reach 0.1';
export const main = Reach.App(() => {
const Alice = Participant('Alice', {goop: Fun([], Bytes(10))});
const Bob = Participant('Bob', {bloop: Fun([Bool], Null)});
deploy();
// write your program here
Alice.only(() => {
const s = declassify(interact.goop());
});
Alice.publish(s);
commit();
Bob.interact.bloop(s == '');
});
// index.mjs
import {loadStdlib} from '@reach-sh/stdlib';
import * as backend from './build/index.main.mjs';
(async () => {
const stdlib = await loadStdlib(process.env);
const startingBalance = stdlib.parseCurrency(100);
const alice = await stdlib.newTestAccount(startingBalance);
const bob = await stdlib.newTestAccount(startingBalance);
const ctcAlice = alice.deploy(backend);
const ctcBob = bob.attach(backend, ctcAlice.getInfo());
console.log(`expected:`);
console.log(true);
console.log(`actual:`);
await Promise.all([
backend.Alice(ctcAlice, { goop: () => '' }),
backend.Bob(ctcBob, { bloop: (b) => console.log(b) }),
]);
console.log('Done');
})();
Output of reach run
:
expected:
true
actual:
false
Hey there! Enjoying learning Reach so far, the tutorial is really well done.
Just going through the tutorial and arrived at this section: https://docs.reach.sh/tut-8.html and running make run-alice
returns the following error, even after docker login
.
[austin:~/projects/reach-hello-wrold] main(+4/-0)* 4s ± make run-alice
docker-compose run --rm alice
Starting reach-hello-wrold_ethereum-devnet_1 ... done
Pulling alice (reachsh/reach-app-tut-8:latest)...
ERROR: pull access denied for reachsh/reach-app-tut-8, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
Makefile:35: recipe for target 'run-alice' failed
make: *** [run-alice] Error 1
The docker-compose.yml
is copied directly from the tutorial. Checking out reachsh on dockerhub and it looks like the docker image indeed does not exist.
Let me know if I can provide any more info, or if I missed a step in the tutorial.
Here is a dump from the error.
make build
docker build --build-arg REACHC_HASH="$(../scripts/git-hash.sh)" --tag="reachsh/reach":latest .
Sending build context to Docker daemon 1.041MB
Step 1/28 : FROM reachsh/haskell-builder:lts-16.12 as build
lts-16.12: Pulling from reachsh/haskell-builder
5d9821c94847: Already exists
a610eae58dfc: Already exists
a40e0eb9f140: Already exists
f5a1b3beb4d5: Pulling fs layer
00f60e56d58b: Pulling fs layer
7da1d9ee2c39: Pulling fs layer
bdcf8775a817: Pulling fs layer
02841cf00f57: Pulling fs layer
6d7b2c61f61a: Pull complete
76f8f84115ee: Pull complete
90a2e469cc7e: Pull complete
0531acd88941: Pull complete
4fd332f6d9c4: Pull complete
d515aee5fda5: Pull complete
Digest: sha256:8de67a4cd2f820b97cfa0b6b7bd18c11a694aaaeab49206387965351dfb57eb1
Status: Downloaded newer image for reachsh/haskell-builder:lts-16.12
---> 692b7e335c77
Step 2/28 : WORKDIR /build
---> Running in 01b510fb14e1
Removing intermediate container 01b510fb14e1
---> f460fba3481e
Step 3/28 : COPY stack.yaml package.yaml stack.yaml.lock ./
---> 4757f74e10af
Step 4/28 : RUN stack build --dependencies-only
---> Running in bdb9a29d3b80
/build/package.yaml: Error while parsing $ - expected Object, but encountered Null
The command '/bin/bash -o pipefail -c stack build --dependencies-only' returned a non-zero code: 1
make: *** [build] Error 1
const FunderInterface =
{
...CommonInterface,
getBounty: Fun([], Object({
deadline: UInt,
amt: UInt,
})),
postWager: Fun([], Null)
}
gives
file:///app/build/index.main.mjs:382
stdlib.protect(ctc2, await interact.postWager(), {
^
TypeError: interact.postWager is not a function
at Module.Funder (file:///app/build/index.main.mjs:382:39)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async Promise.all (index 0)
at async file:///app/index.mjs:122:5
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @reach-sh/stonk-wars-index@ index: `node --experimental-modules --unhandled-rejections=strict index.mjs`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @reach-sh/stonk-wars-index@ index 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! /root/.npm/_logs/2021-06-11T02_59_57_847Z-debug.log
ERROR: 1
Makefile.index:20: recipe for target 'run-target' failed
make[1]: *** [run-target] Error 1
make[1]: Leaving directory '/mnt/d/my-projs/stonk-wars'
Makefile.index:16: recipe for target 'run' failed
make: *** [run] Error 2
how to create .rsh document
where to use reach ? VsCode?
The following code
'reach 0.1';
'use strict';
const TIMEOUT_PERIOD = 60 * 1000;
//const MINIMUM_FEE = 1000;
//-----------------------------------------------------------------------------
// Token operative & compliance parameters
//-----------------------------------------------------------------------------
const TokenParameters = Object({
maxTransfers: UInt,
})
//-----------------------------------------------------------------------------
// Interaction interfaces
//-----------------------------------------------------------------------------
const IManager = {
getBootstrapParams: Fun([], Tuple(Token, TokenParameters)),
setupComplete: Fun([], Null)
}
const ISender = {
getAxfer: Fun([], Tuple(UInt))
}
const IReceiver = {
accAxfer: Fun([UInt], Bool)
}
//-----------------------------------------------------------------------------
// Helper functions
//-----------------------------------------------------------------------------
function validateParams(params) {
assume(params.maxTransfers >= 1);
}
//-----------------------------------------------------------------------------
// DApp Entry point
//-----------------------------------------------------------------------------
export const main = Reach.App(
{}, [
Participant('Manager', IManager),
ParticipantClass('Sender', ISender),
ParticipantClass('Receiver', IReceiver)],
(Manager, Sender, Receiver) => {
// Step1:Manager must set token parameters
Manager.only(() => {
const [token, params] = declassify(interact.getBootstrapParams());
validateParams(params);
interact.setupComplete();
})
Manager.publish(token, params);
var run = true
invariant (balance() == 0 && balance(token) == 0)
while(run) {
Sender.only(() => {
})
Receiver.only(() => {
})
commit()
Anybody.publish()
continue;
}
commit();
}
);
will cause an internal compiler error as follows:
Verifying knowledge assertions
Verifying for generic connector
Verifying when ALL participants are honest
Verifying when NO participants are honest
Verifying when ONLY "Manager" is honest
Verifying when ONLY "Receiver" is honest
Verifying when ONLY "Sender" is honest
Checked 34 theorems; No failures!
reachc: The compiler has encountered an internal error:
3 lookup_let v29 not in v33, v49, v51, v56, v351, v352
This error indicates a problem with the Reach compiler, not your program. Please report this error, along with the pertinent program, to the Reach team as soon as possible so we can fix it.
Open an issue at: https://github.com/reach-sh/reach-lang/issues
CallStack (from HasCallStack):
error, called at src/Reach/Util.hs:66:3 in reach-0.1.2-1JzW2Z5sBxAzanGaqepiq:Reach.Util
impossible, called at src/Reach/Connector/ALGO.hs:336:7 in reach-0.1.2-1JzW2Z5sBxAzanGaqepiq:Reach.Connector.ALGO
Thanks.
I'm experiencing an awkward error when nesting parallelReduce(). I'm not sure whether this is expected behavior or a bug. Specifically I'm encountering Example 4, but found the same error for a different situation in Example 3.
A non-nested PR that uses participant A in multiple cases passes verification: https://github.com/reach-sh/reach-lang/blob/master/examples/multiple-pr-case/index.rsh
When nested PRs use different participants in their cases, the code passes verification.
'reach 0.1';
const Common = ({
doCase: Fun([UInt], Bool) });
export const main = Reach.App(
{}, [Participant('A', {...Common}), Participant('B', {...Common})], (A, B) => {
A.publish()
.pay(1);
commit();
B.publish();
const keepGoing =
parallelReduce(true)
.invariant(balance() == 1)
.while(keepGoing)
.case(
A,
(() => ({ when: true })),
((_) => {
const keepGoingB =
parallelReduce(true)
.invariant(balance() == 1)
.while(keepGoingB)
.case(
B,
(() => ({ when: declassify(interact.doCase(1)) })),
() => { return true; })
.timeout(1000, () => {
Anybody.publish();
return false;
});
return false;
})
)
.timeout(false);
transfer(1).to(B);
commit();
exit();
}
);
When a case on the outer PR uses the same participant as a case on the inner PR, an error is thrown: reachc: error: ./index.rsh:24:29:const: Invalid name shadowing. Identifier 't' is already bound at ./index.rsh:15:21:id. It cannot be bound again at ./index.rsh:24:29:id
'reach 0.1';
const Common = ({
doCase: Fun([UInt], Bool) });
export const main = Reach.App(
{}, [Participant('A', {...Common}), Participant('B', {...Common})], (A, B) => {
A.publish()
.pay(1);
commit();
B.publish();
const keepGoing =
parallelReduce(true)
.invariant(balance() == 1)
.while(keepGoing)
.case(
A,
(() => ({ when: true })),
((_) => {
const keepGoingB =
parallelReduce(true)
.invariant(balance() == 1)
.while(keepGoingB)
.case(
A,
(() => ({ when: declassify(interact.doCase(1)) })),
() => { return true; })
.timeout(1000, () => {
Anybody.publish();
return false;
});
return false;
})
)
.timeout(false);
transfer(1).to(B);
commit();
exit();
}
);
When a case on the outer PR uses participant A, and the inner PR uses participant B in multiple cases, an error is thrown: reachc: error: ./index.rsh:24:29:application: Invalid name shadowing. Identifier 't' is already bound at ./index.rsh:15:21:id. It cannot be bound again at ./index.rsh:24:29:id
. Given that examples 1 and 2 both pass verification, it seems like this should pass as well, yet it does not.
'reach 0.1';
const Common = ({
doCase: Fun([UInt], Bool) });
export const main = Reach.App(
{}, [Participant('A', {...Common}), Participant('B', {...Common})], (A, B) => {
A.publish()
.pay(1);
commit();
B.publish();
const keepGoing =
parallelReduce(true)
.invariant(balance() == 1)
.while(keepGoing)
.case(
A,
(() => ({ when: true })),
((_) => {
const keepGoingB =
parallelReduce(true)
.invariant(balance() == 1)
.while(keepGoingB)
.case(
B,
(() => ({ when: declassify(interact.doCase(1)) })),
() => { return true; })
.case(
B,
(() => ({ when: declassify(interact.doCase(2)) })),
() => { return true; })
.timeout(1000, () => {
Anybody.publish();
return false;
});
return false;
})
)
.timeout(false);
transfer(1).to(B);
commit();
exit();
}
);
I had released a bug report on this. It was fixed and now the issue has returned.
{"contracts":{"index.sol:DaiToken":{"abi":"[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"remaining","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]","bin":"60c0604052600e60808190526d26b7b1b5902220a4902a37b5b2b760911b60a090815261002f916000919061009c565b50604080518082019091526004808252636d44414960e01b602090920191825261005b9160019161009c565b5069d3c21bcecceda10000006002556003805460ff1916601217905534801561008357600080fd5b506002543360009081526004602052604090205561013d565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826100d25760008555610118565b82601f106100eb57805160ff1916838001178555610118565b82800160010185558215610118579182015b828111156101185782518255916020019190600101906100fd565b50610124929150610128565b5090565b5b808211156101245760008155600101610129565b61063f8061014c6000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063324536eb11610071578063324536eb1461020a5780635c6581651461021257806370a082311461024057806395d89b4114610266578063a9059cbb1461026e578063dd62ed3e1461029a576100b4565b806306fdde03146100b9578063095ea7b31461013657806318160ddd1461017657806323b872dd1461019057806327e235e3146101c6578063313ce567146101ec575b600080fd5b6100c16102c8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100fb5781810151838201526020016100e3565b50505050905090810190601f1680156101285780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101626004803603604081101561014c57600080fd5b506001600160a01b038135169060200135610356565b604080519115158252519081900360200190f35b61017e6103bc565b60408051918252519081900360200190f35b610162600480360360608110156101a657600080fd5b506001600160a01b038135811691602081013590911690604001356103c2565b61017e600480360360208110156101dc57600080fd5b50356001600160a01b03166104a1565b6101f46104b3565b6040805160ff9092168252519081900360200190f35b61017e6104bc565b61017e6004803603604081101561022857600080fd5b506001600160a01b03813581169160200135166104c2565b61017e6004803603602081101561025657600080fd5b50356001600160a01b03166104df565b6100c16104fa565b6101626004803603604081101561028457600080fd5b506001600160a01b038135169060200135610554565b61017e600480360360408110156102b057600080fd5b506001600160a01b03813581169160200135166105de565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561034e5780601f106103235761010080835404028352916020019161034e565b820191906000526020600020905b81548152906001019060200180831161033157829003601f168201915b505050505081565b3360008181526005602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b60025490565b6001600160a01b0383166000908152600460205260408120548211156103e757600080fd5b6001600160a01b038416600090815260056020908152604080832033845290915290205482111561041757600080fd5b6001600160a01b0380851660008181526004602090815260408083208054889003905593871680835284832080548801905583835260058252848320338452825291849020805487900390558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b60046020526000908152604090205481565b60035460ff1681565b60025481565b600560209081526000928352604080842090915290825290205481565b6001600160a01b031660009081526004602052604090205490565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561034e5780601f106103235761010080835404028352916020019161034e565b3360009081526004602052604081205482111561057057600080fd5b336000818152600460209081526040808320805487900390556001600160a01b03871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350600192915050565b6001600160a01b0391821660009081526005602090815260408083209390941682529190915220549056fea264697066735822122069b843f35deddce2866f47f91b1f8e6f8ae4355079f426093b065fb8146a7b8864736f6c63430007040033"}},"version":"0.7.4+commit.3f05b770.Darwin.appleclang"}file:///app/index.mjs:21 const remoteABI = remoteCtc["abi"]; ^
TypeError: Cannot read property 'abi' of undefined at file:///app/index.mjs:21:30
The following parallelReduce loop will yield
reachc: error: ./registry.rsh:23:41:application: Administrator is bound and cannot be rebound
'reach 0.1'
'use strict'
const IAdministrator = {
getNewEntry: Fun([],Address),
shouldStop: Fun([], Bool)
}
const IRegistryView = {
last: UInt
}
export const main = Reach.App({
deployMode: "constructor"
},
[ Participant('Administrator', IAdministrator),
View('RegistryView', IRegistryView) ],
(Admin, RegistryView) => {
Admin.publish();
const registry = new Set()
const isRunning = parallelReduce(true)
.invariant(balance () == 0) // No funds movement, should validate always
.while(isRunning)
.case(
Admin,
/* publish_expr */
(() => ({ when: declassify(interact.shouldStop()) })),
/* pay_expr */
((_) => 0),
/* consensus_expr */
(() => {
return false;
})
)
.case(
Admin,
/* publish_expr */
(() => ({ msg: declassify(interact.getNewEntry()) })),
/* pay_expr */
((_) => 0),
/* consensus_expr */
((addr) => {
registry.insert(addr);
return isRunning;
})
)
commit();
})
Thanks in advance.
In workshops 1-5, the directions tell the user to mkdir
the workshop directory, and then, assuming that the user has changed directory into the new directory, the directions tell the user to run ../reach version
to verify that the script will run. Perhaps we should be more explicit so that copy/paste users don't get tripped up.
Tutorial 2.1 avoids this confusion by using mkdir -p ~/reach/tut && cd ~/reach/tut
. This approach is probably the most bang for the least buck. This involves a change to lib-rkt
.
Another approach might be to use ~/reach/reach
throughout.
One more idea to consider: Currently, reach-lang
has a particular directory structure. I can git clone
it to my computer, cd
to any tutorial or workshop, and run the example using ~/reach-lang/reach
. I can add same to my path
variable. I can also set my VSCode Reach IDE extension Executable Location
variable to same. We could use this same directory structure for our "learning" directory structure, but change the root directory name from reach-lang
to something else. We could choose reach-learn
, but I think it is too similar to reach-lang
. A better choice, perhaps, might be reach-study
. Thx.
Summary
Section and Link
Issue
Recommendation
Supporting Links
"...if Bob does not complete perform this action within a..."
docs-src/tut.scrbl line 1007
I understand this has been reported, and am creating an issue to help track it as suggested.
Although the .rsh
file compiles with no failures, the following error is encountered when running the app in the browser:
Uncaught Error: hexAddress should be passed as a Buffer
Encountered while building a Reach application inspired by the NFT Dumb example. Tested as far back as rc-46
of stdlib.
File contents below.
"reach 0.1";
const AuctionProps = Object({
assetId: UInt,
description: Bytes(128),
price: UInt,
});
const BuyerProps = {
getBid: Fun([UInt], UInt),
getNewOwner: Fun([], Address),
showSaleItem: Fun([], Null),
};
const OwnerInterface = {
getSaleProps: Fun([], AuctionProps),
...BuyerProps,
};
export const main = Reach.App(() => {
const Owner = Participant("Owner", OwnerInterface);
const Buyer = ParticipantClass("Buyer", BuyerProps);
const vNFTSale = View("vNFTSale", {
assetId: UInt,
description: Bytes(128),
owner: Address,
price: UInt,
});
deploy();
Owner.only(() => {
const props = declassify(interact.getSaleProps());
});
Owner.publish(props);
vNFTSale.assetId.set(props.assetId);
vNFTSale.description.set(props.description);
vNFTSale.owner.set(Owner);
vNFTSale.price.set(props.price);
var owner = Owner;
invariant(balance() == 0);
while (owner == Owner) {
commit();
Buyer.only(() => {
// Show what's on sale (allows the front-end to use vNFTSale)
interact.showSaleItem();
const amOwner = this == owner;
// Allow Owner to specify a receiver address directly, and pay nothing
const price = amOwner ? 0 : declassify(interact.getBid(props.price));
const newOwner = amOwner ? declassify(interact.getNewOwner()) : this;
});
Buyer.publish(price, newOwner).pay(price);
transfer(balance()).to(Owner);
owner = newOwner;
continue;
}
commit();
exit();
});
At first I thought I had made a mistake when following the tutorial found at https://docs.reach.sh/tut-8.html but it appears there may be something going on in the image.
Steps to reproduce:
package.json
, Makefile
, index.rsh
, index.mjs
, docker-compose.yml
, Dockerfile
into a directory&default-app
from reach-app-tut-8-ETH-test-dockerized-geth
to reach-app-tut-8-ALGO-test-dockerized-algod
./reach compile
make build
make run-alice
Output is as follows:
MacBook-Pro-6:tut $ make run-alice
docker-compose run --rm alice
Starting tut_algorand-postgres-db_1 ... done
Starting tut_algorand-devnet_1 ... done
> @reach-sh/tut-8@ index /app
> node --experimental-modules --unhandled-rejections=strict index.mjs
(node:18) ExperimentalWarning: The ESM module loader is experimental.
Are you Alice?
y
Starting Rock, Paper, Scissors! as Alice
Would you like to create an account? (only possible on devnet)
y
Do you want to deploy the contract? (y/n)
y
/stdlib/node_modules/algosdk/src/transaction.js:181
throw Error(
^
Error: Application global byte slices count must be a positive number and smaller than 2^53-1
at new Transaction (/stdlib/node_modules/algosdk/src/transaction.js:181:13)
at Object.makeApplicationCreateTxn (/stdlib/node_modules/algosdk/src/makeTxn.js:930:10)
at deployP (file:///stdlib/ALGO.mjs:975:86)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @reach-sh/tut-8@ index: `node --experimental-modules --unhandled-rejections=strict index.mjs`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @reach-sh/tut-8@ index script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
I tried to find some information about what is happening but I don't know much about Algorand at this point. The best I could do was this PyTeal Docs page, explaining the global_num_byte_slices
enum which matches the error message https://pyteal.readthedocs.io/en/latest/api.html#pyteal.TxnField.global_num_byte_slices
Description
This page describes the different programs Reach uses. Adding context to when you'd use it for each section would be very helpful I think.
For example: Under 'switch'. If you put just a sentence or two like, "You would use this in a scenario where Alice x with Bob... etc'
Page Link
https://docs.reach.sh/ref-programs-compute.html#%28tech._value._definition%29
Search String
"A switch statement, written switch (VAR) { CASE ... }, where VAR is a variable bound to..."
Issue
These programs are useful but seem to be floating in mid air. Let's spoil the developers and let them see how we use them!
Suggestion
I think these programs need some more context about when to apply them.
I need to keep Reach compiler version on my computer in sync with the cdn.jsdelivr.net webpack version. I suggest adding more explicit output for reach --version
like this:
% reach --version
reach 0.1.2-rc.58
I'm receiving this error in projects that implement a Relay account. Here's the debug information for an interactive test runner. Using the Relay example
Starting example game as Relay
Would you like to create an account? (only possible on devnet)
y
Do you want to deploy the contract? (y/n)
n
Please paste the contract information:
{"address":"0xC87539117dfE46FEa8366eFaef3c37C1520e4BeF","creation_block":597,"transactionHash":"0xe7972ce74878e5af997396e9fa908a494d067ce14481cbfc124d8a24cbb52e61"}
Relay balance is: 1000
Alice creates a Relay account.
Alice shares it with Bob outside of the network. {"_isSigner":true,"address":"0x26beBf4a1a4688d8764b85D429e70BAD5171c432","provider":{"_isProvider":true,"_events":[],"_emitted":{"block":-2,"t:0x34c10f3768c7e43d32657f40e79151d324fdc22e03f7be32d7a26d6eda315b32":600,"t:0xd6b518f69dcbd3500dc1efa48b8f6780e2dedc91caf50f2d1c320ca96c72d661":601},"formatter":{"formats":{"transaction":{},"transactionRequest":{},"receiptLog":{},"receipt":{},"block":{},"blockWithTransactions":{},"filter":{},"filterLog":{}}},"anyNetwork":false,"_networkPromise":{},"_maxInternalBlockNumber":601,"_lastBlockNumber":-2,"_pollingInterval":500,"_fastQueryDate":1625760988942,"connection":{"url":"http://ethereum-devnet:8545"},"_nextId":74,"_eventLoopCache":{"detectNetwork":null,"eth_chainId":null,"eth_blockNumber":null},"_network":{"chainId":1337,"name":"unknown"},"_internalBlockNumber":{},"_fastBlockNumber":601,"_fastBlockNumberPromise":{}}}
impossible: The message you are trying to send appears to be invalid.
Error: execution reverted
at getResult (/stdlib/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:128:21)
at processJsonFunc (/stdlib/node_modules/@ethersproject/web/lib/index.js:309:22)
at /stdlib/node_modules/@ethersproject/web/lib/index.js:241:46
at step (/stdlib/node_modules/@ethersproject/web/lib/index.js:33:23)
at Object.next (/stdlib/node_modules/@ethersproject/web/lib/index.js:14:53)
at fulfilled (/stdlib/node_modules/@ethersproject/web/lib/index.js:5:58)
at runMicrotasks ()
at processTicksAndRejections (internal/process/task_queues.js:95:5) {
code: 3,
data: '0x100960cb0000000000000000000000000000000000000000000000000000000000000008'
}
args:
[
[ BigNumber { _hex: '0x0255', _isBigNumber: true } ],
[
BigNumber { _hex: '0x015af1d78b58c40000', _isBigNumber: true },
'0x26beBf4a1a4688d8764b85D429e70BAD5171c432'
]
]
/stdlib/dist/cjs/ETH_like.js:786
throw Error(dhead + " REPEAT @ " + block_send_attempt + " x " + block_repeat_count);
^
Error: 26be,26be,send,m1,false,SEND REPEAT @ 601 x 33
at Object. (/stdlib/dist/cjs/ETH_like.js:786:51)
at step (/stdlib/dist/cjs/ETH_like.js:44:23)
at Object.next (/stdlib/dist/cjs/ETH_like.js:25:53)
at fulfilled (/stdlib/dist/cjs/ETH_like.js:16:58)
at runMicrotasks ()
====
This also appears on Algorand here is the test runner debug information.
Please paste the contract information:
{"ApplicationID":2,"creationRound":13,"Deployer":"6J3K2FVIHK2IEXRIJ52JMZHM3J5XDY7NGZUIZP3FXXSG276OGNKFX3JVXI"}
Relay balance is: 1000
Alice creates a Relay account.
Alice shares it with Bob outside of the network. {"addr":"HYBRXGYCFV56TVVFMSDDMVVB36FZB72GVXLCHZ4SDTPPYTIUJOYGKLPZNE","sk":{"0":107,"1":230,"2":121,"3":162,"4":155,"5":30,"6":171,"7":186,"8":175,"9":205,"10":189,"11":57,"12":130,"13":222,"14":139,"15":136,"16":40,"17":97,"18":63,"19":190,"20":164,"21":215,"22":180,"23":213,"24":62,"25":49,"26":28,"27":203,"28":185,"29":40,"30":217,"31":216,"32":62,"33":3,"34":27,"35":155,"36":2,"37":45,"38":123,"39":233,"40":214,"41":165,"42":100,"43":134,"44":54,"45":86,"46":161,"47":223,"48":139,"49":144,"50":255,"51":70,"52":173,"53":214,"54":35,"55":231,"56":146,"57":28,"58":222,"59":252,"60":77,"61":20,"62":75,"63":176}}
/stdlib/dist/cjs/ALGO.js:1461
throw Error(dhead + " --- ABORT");
^
Error: BRXG: BRXG sendrecv m1 false --- ABORT
at /stdlib/dist/cjs/ALGO.js:1461:67
at step (/stdlib/dist/cjs/ALGO.js:66:23)
at Object.throw (/stdlib/dist/cjs/ALGO.js:47:53)
at step (/stdlib/dist/cjs/ALGO.js:51:139)
at Object.throw (/stdlib/dist/cjs/ALGO.js:47:53)
at rejected (/stdlib/dist/cjs/ALGO.js:39:65)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
Array
in a while
loop
Addresses
parallelReduce
Verifying knowledge assertions
Verifying for generic connector
Verifying when ALL participants are honest
Verification failed:
when ALL participants are honest
of theorem: assert
msg: "balance zero at application exit"
at ./index.rsh:74:7:application
reachc: The compiler has encountered an internal error:
parseVal: Array(Address, 2) List [List [Atom "as",Atom "const",List [Atom "Array",Atom "Int",Atom "Address"]],Atom "Address!val!0"]
This error indicates a problem with the Reach compiler, not your program. Please report this error, along with the pertinent program, to the Reach team as soon as possible so we can fix it.
Open an issue at: https://github.com/reach-sh/reach-lang/issues
CallStack (from HasCallStack):
error, called at src/Reach/Util.hs:73:3 in reach-0.1.2-DAFksisXDyRKXmySyEXCbN:Reach.Util
impossible, called at src/Reach/Verify/SMT.hs:467:10 in reach-0.1.2-DAFksisXDyRKXmySyEXCbN:Reach.Verify.SMT
"reach 0.1";
const AuctionProps = {
arbitrator: Array(Address, 2),
assetId: Token,
price: UInt,
quantity: UInt,
};
const BuyerProps = {
getPurchaseAmount: Fun([UInt, UInt], UInt),
showSaleItem: Fun([], Null),
};
const OwnerInterface = {
getSaleProps: Fun([], Object(AuctionProps)),
...BuyerProps,
};
export const main = Reach.App(() => {
const Owner = Participant("Owner", OwnerInterface);
const Buyer = ParticipantClass("Buyer", BuyerProps);
deploy();
// Set up sale-item details
Owner.only(() => {
const sale = declassify(interact.getSaleProps());
const token = sale.assetId;
});
// Pay token to contract
Owner.publish(sale, token).pay([[sale.quantity, token]]);
commit();
Buyer.publish();
var inStock = sale.quantity;
invariant(balance(token) == inStock);
while (inStock > 0) {
commit();
Buyer.only(() => {
// Show what's on sale (allows the front-end to use vNFTSale)
interact.showSaleItem();
const qty = declassify(interact.getPurchaseAmount(inStock, sale.price));
assume(qty > 0, "You need to purchase at least 1 item!");
const buyerPmt = qty * sale.price;
assume(qty <= inStock, "There aren't that many items left!");
});
// Only attempt to purchase when buyer wants more than 0 items
Buyer.publish(qty, buyerPmt)
.when(buyerPmt > 0)
.pay(buyerPmt)
.timeout(false);
// Transfer quantity of purchased NFTs to buyer
transfer(qty, token).to(this);
// Payout participants => This is likely where the rage occurs.
// The exact same chunk works in a `parallelReduce`
const arbFee = (buyerPmt * (2 / 100)) / Array.length(sale.arbitrator);
Array.forEach(sale.arbitrator, (a) => {
transfer(arbFee).to(a);
});
transfer(balance()).to(Owner);
// Update number of items left to sell
const inventory = inStock - qty;
inStock = inventory;
continue;
}
commit();
exit();
});
The program is in a fairly finished state so I'd rather keep it private. I'll pass the source along to Jay.
Encountering the following error:
reachc: The compiler has encountered an internal error:
lookup_var v73
This error indicates a problem with the Reach compiler, not your program. Please report this error, along with the pertinent program, to the Reach team as soon as possible so we can fix it.
Open an issue at: https://github.com/reach-sh/reach-lang/issues
CallStack (from HasCallStack):
error, called at src/Reach/Util.hs:73:3 in reach-0.1.2-DAFksisXDyRKXmySyEXCbN:Reach.Util
impossible, called at src/Reach/Connector/ALGO.hs:388:16 in reach-0.1.2-DAFksisXDyRKXmySyEXCbN:Reach.Connector.ALGO
Verifying knowledge assertions
Verifying for generic connector
Verifying when ALL participants are honest
Verifying when NO participants are honest
Verifying when ONLY "HandcraftedFeeAcct" is honest
Verifying when ONLY "HandcraftedTaxAcct" is honest
Verifying when ONLY "Merchant" is honest
Verifying when ONLY "PotentialBuyer" is honest
Checked 156 theorems; No failures!
make: *** [Makefile.index:8: build/index.main.mjs] Error 1
'reach 0.1';
// ========================================================
// Helper Functions
// ========================================================
const emptyOrderMetadata = {
taxAmt: 0,
shippingAmt: 0,
unitPrice: 0,
orderID: 0,
orderTotal: 0
}
const setViewActiveOrderMetadata = (view, orderMetadata) => {
view.taxAmt.set(orderMetadata.taxAmt);
view.shippingAmt.set(orderMetadata.shippingAmt);
view.orderID.set(orderMetadata.orderID);
view.unitPrice.set(orderMetadata.unitPrice);
view.orderTotal.set(orderMetadata.orderTotal);
}
const resetViewActiveOrderMetadata = (view) => {
setViewActiveOrderMetadata(view, emptyOrderMetadata);
}
const countTrue = (arr) => arr.reduce(0, (z, x) => z + (x ? 1 : 0))
// ========================================================
// Participants
// ========================================================
// This may need to track more info about contract state.
const OrderMetadataInterface = {
taxAmt: UInt,
shippingAmt: UInt,
orderID: UInt,
unitPrice: UInt,
orderTotal: UInt
}
const OrderMetadataTypes = [
UInt, UInt, UInt, UInt, UInt,
]
const MerchantInterface = {
getTrialData: Fun([], Object({
initialTrialDurationInDays: UInt,
trueUnitPrice: UInt,
})),
getArbiterAddresses: Fun([], Object({
feeAddr: Address,
taxAddr: Address
})),
showOrderCreated: Fun([], Null),
wantsToApproveOrder: Fun([], Bool),
wantsToDenyOrder: Fun([], Bool),
markOrderApprovedAndShipped: Fun([], Null)
}
const potentialBuyerErrors = {
errorDepositHasAlreadyBeenMade: Fun([], Null),
errorOrderDenied: Fun([], Null)
}
const potentialBuyerAlerts = {
alertItemDidNotShip: Fun([], Null),
}
const PotentialBuyerInterface = {
intendsToPurchase: Fun([], Bool),
getOrderInfo: Fun([], Object(OrderMetadataInterface)),
showOrderPaid: Fun(OrderMetadataTypes, Null),
syncToDb: Fun(OrderMetadataTypes, Null),
...potentialBuyerErrors,
...potentialBuyerAlerts
}
const ViewInterface = {
...OrderMetadataInterface
}
// ========================================================
// Main Contract Logic
// ========================================================
export const main = Reach.App(
{}, [
Participant('Merchant', MerchantInterface),
ParticipantClass('PotentialBuyer', PotentialBuyerInterface),
View('ActiveOrderMetadata', ViewInterface),
Participant('HandcraftedFeeAcct', {}),
Participant('HandcraftedTaxAcct', {}),
], (Merchant, PotentialBuyer, vActiveOrderMetadata, HandcraftedFeeAcct, HandcraftedTaxAcct) => {
Merchant.only(() => {
const { initialTrialDurationInDays, trueUnitPrice } = declassify(interact.getTrialData());
const { feeAddr, taxAddr } = declassify(interact.getArbiterAddresses());
declassify(interact.showOrderCreated());
});
Merchant.publish(initialTrialDurationInDays, trueUnitPrice, feeAddr, taxAddr);
HandcraftedFeeAcct.set(feeAddr);
HandcraftedTaxAcct.set(taxAddr);
assert(balance() == 0);
/**
* @var {Bool} hasBeenPurchased
* If true, the item has been successfully sold and should
* therefore no longer be listed as available for purchase,
* either in the contract logic or in the frontend/db.
* @var {OrderMetadataInterface} finalPaymentAmts
* The order metadata to be used for final payouts.
*/
const [ hasBeenPurchased, finalPaymentAmts ] =
parallelReduce([ false, emptyOrderMetadata])
.invariant(balance() == finalPaymentAmts.orderTotal)
.while(!hasBeenPurchased)
// Steps 2 & 3 - Potential buyer makes a deposit.
.case(PotentialBuyer,
(() => ({
when: declassify(interact.intendsToPurchase())
})),
((_) => {
// We can assume that a deposit has been made if
// the balance is greater than 0. It is not enough
// to check for a loop var depositIsActive
// because that is set at the end of the step,
// but a second user may make end up making a deposit
// between when the first user makes a deposit and
// the loop returns the updated depositIsActive.
if(balance() > 0) {
PotentialBuyer.only(() => declassify(interact.errorDepositHasAlreadyBeenMade()));
return [
hasBeenPurchased,
finalPaymentAmts
];
} else {
const ThisPotentialBuyer = this;
assert(balance() == 0);
commit();
// Buyer publishes supposed order data from the frontend to be paid
PotentialBuyer.only(() => {
// We are having the buyer provide the orderTotal from the front end,
// so we need to have outside validation of this as well.
const orderMetadata = declassify(interact.getOrderInfo());
const { taxAmt, shippingAmt, unitPrice, orderID, orderTotal } = orderMetadata;
declassify(interact.showOrderPaid(taxAmt, shippingAmt, unitPrice, orderID, orderTotal));
// This needs to be fleshed out.
declassify(interact.syncToDb(taxAmt, shippingAmt, unitPrice, orderID, orderTotal));
});
PotentialBuyer.publish(orderMetadata)
.pay(orderMetadata.orderTotal);
assert(balance() == orderMetadata.orderTotal);
setViewActiveOrderMetadata(vActiveOrderMetadata, orderMetadata);
// 4. Approval/refund logic
const [ orderTimedOut, orderDenied, orderApproved ] =
parallelReduce([ false, false, false ])
.invariant((countTrue(array(Bool, [orderTimedOut, orderDenied, orderApproved])) <= 1)
&& (balance() == orderMetadata.orderTotal))
.while(!orderTimedOut && !orderDenied && !orderApproved)
.case(
Merchant,
(() => ({ when: declassify(interact.wantsToApproveOrder())})),
() => { return [ false, false, true ]; }
)
// Commented out until fix is released: https://github.com/reach-sh/reach-lang/issues/205#issuecomment-873118085
// .case(
// Merchant,
// (() => ({ when: declassify(interact.wantsToDenyOrder())})),
// () => { return [ false, true, false ]; }
// )
//
// Test case, not true timeout.
.timeout(1000, () => {
Anybody.publish();
return [ false, false, true ];
});
// Verification fails without this. Seems like it's needed
// to protect against some sort of malicious activity in
// the timeout due to Anybody.publish().
if(balance() != orderMetadata.orderTotal) {
transfer(balance()).to(ThisPotentialBuyer);
return [ false, emptyOrderMetadata];
} else {
return [ true, orderMetadata ];
}
}
})
)
.timeout(false);
commit();
Anybody.publish();
transfer(finalPaymentAmts.orderTotal).to(Merchant);
commit();
exit();
}
);
Description
This section is supposed to explain that these are all assertions but I don't think it's clear. I think it refers to some as assertions and some not, when they all are.
Page Link
https://docs.reach.sh/ref-model.html
Search String
"An assertion is either: a knowledge assertion, which is a claim that one honest participant..."
Issue
I talked to Jay about this and it turns out they are all assertions. Here is what was discussed:
Me: Are 'assumption' and 'requirement' also types of assertions? This wording is confusing.
Jay: Yes. There are assertions of five flavors: static, assumption, requirement, possibility, knowledge. The functions that get you them in the code are assert, assume, require, possible, unknowable
Suggestion
Just clarifying that these are all, in fact, assumptions, helped me group the info and make a better note of it.
https://gist.github.com/Zetsuboii/05e473ac22d1ebd176ed8b0b126ecc7a
This is what I've written to produce the error.
https://gist.github.com/Zetsuboii/3e5792bdfeb3970e5a4eeae4ea856404
This is a similar code without the loop
Without the loop, compiler only evaluates the possible branches.
But when loop is involved const temp = i < 5 ? arr[i] : i;
this line, which normally would work fine because arr has the length of 5, gives array out of bounds error.
The attached code below will yield the following :
reachc: The compiler has encountered an internal error:
getIllegalModeSuggestion
This error indicates a problem with the Reach compiler, not your program. Please report this error, along with the pertinent program, to the Reach team as soon as possible so we can fix it.
Open an issue at: https://github.com/reach-sh/reach-lang/issues
CallStack (from HasCallStack):
error, called at src/Reach/Util.hs:66:3 in reach-0.1.2-1JzW2Z5sBxAzanGaqepiq:Reach.Util
impossible, called at src/Reach/Eval/Error.hs:254:12 in reach-0.1.2-1JzW2Z5sBxAzanGaqepiq:Reach.Eval.Error
Thank you.
Code:
'reach 0.1';
'use strict';
//-----------------------------------------------------------------------------
// Token operative & compliance parameters
//-----------------------------------------------------------------------------
const TokenParameters = Object({
maxTransfers: UInt,
})
//-----------------------------------------------------------------------------
// Interaction interfaces
//-----------------------------------------------------------------------------
const IManager = {
getBootstrapParams: Fun([], Tuple(Token, TokenParameters)),
setupComplete: Fun([], Null),
shouldStop: Fun([], Bool)
}
const ISender = {
getAxfer: Fun([], Maybe(Tuple(UInt, Address)))
}
//-----------------------------------------------------------------------------
// Helper functions
//-----------------------------------------------------------------------------
function validateParams(params) {
assume(params.maxTransfers > 0);
}
//-----------------------------------------------------------------------------
// DApp Entry point
//-----------------------------------------------------------------------------
export const main = Reach.App(
{
deployMode: 'constructor'
}, [
Participant('Manager', IManager),
Participant('Sender', ISender)
],
(Manager, Sender) => {
// Step1:Manager must set token parameters
Manager.only(() => {
const [token, params] = declassify(interact.getBootstrapParams());
validateParams(params);
interact.setupComplete();
})
Manager.publish(token, params);
commit();
Sender.publish();
const run = parallelReduce(true)
.invariant(balance() == 0 && balance(token) == 0)
.while(run)
.case(Manager,
(() => ({ when: declassify(interact.shouldStop()) })),
((_) => 0),
() => { return false }
)
.case(Sender,
(() => {
const axferParams = declassify(interact.getAxfer());
return {
msg: fromSome(axferParams, [0, this]),
when: isSome(axferParams)
}
}),
((axferParams) => {
const amount = axferParams[0];
assume(amount > 0, "EZERO");
return [amount, token]
}),
((axferParams) => {
const amount = axferParams[0];
const rcvAddr = axferParams[1];
transfer(amount, token).to(rcvAddr);
return true;
})
)
}
);
In tutorial 9, the contract information is rendered after deploying the contract as Alice. Before I attach to the contract as Bob, the following unhandled exception shows up:
Steps to reproduce:
To open the react application:
2. ./reach react
This happens when using the Ropsten test network, but works fine when using Ganache.
Experiencing the following on ./reach run
, although all theorums appear to be passing. I'm sure there are issues with the test front end since I just finished mocking up the initial draft, but not sure whether or not that shoud/would affect compilation. I should note that I'm seeing the same whether the MAX_XYZ constants are >= 1.
Compiler error: Stack too deep when compiling inline assembly: Variable dataEnd is 2 slot(s) too deep inside the stack.
CallStack (from HasCallStack):
error, called at src/Reach/Util.hs:73:3 in reach-0.1.2-8gxBL61FkZIAAO2AD266di:Reach.Util
impossible, called at src/Reach/Connector/ETH_Solidity.hs:1368:17 in reach-0.1.2-8gxBL61FkZIAAO2AD266di:Reach.Connector.ETH_Solidity
make: *** [Makefile.index:8: build/index.main.mjs] Error 1
"reach 0.1";
// ========================================================
// Constants
// ========================================================
// Since reach cannot really handle floating point numbers.
const BAKESALE_FEE_PERCENT = 5;
const BAKESALE_FEE_MULTIPLE = BAKESALE_FEE_PERCENT / 100;
const MAX_BENEFICIARIES_PER_ITEM = 1;
const MAX_LINE_ITEMS_PER_MERCHANT = 1;
const MAX_TOTAL_MERCHANTS = 1;
// ========================================================
// Primary Objects & Their Fakers
// ========================================================
/**
* Create an "isReal" version of an object.
*
* @param {object} x
* The object to clarify as real.
* @param {bool} state
* Whether or not the object is real.
* @returns {object}
* The initial object with an isReal prop added.
*/
const createIsReal = (state, x) => ({
isReal: state,
...x
});
/**
* The beneficiary of a particular item.
*/
const Beneficiary = {
isReal: Bool,
addr: Address,
percentToReceive: UInt,
};
/**
* Create a fake benficiary.
*
* @param addr
* The fake address.
* @returns
* The fake Beneficiary.
*/
const createFakeBeneficiary = (addr) => {
return createIsReal(false, {
addr,
percentToReceive: 0}
);
}
/**
* An order line item.
*/
const LineItem = {
isReal: Bool,
totalCost: UInt, // The unit price * qty
shipping: UInt,
tax: UInt,
beneficiaries: Array(Maybe(Object(Beneficiary)), MAX_BENEFICIARIES_PER_ITEM)
}
/**
* Create a fake LineItem.
*
* @param addr
* The fake address.
* @returns
* The fake LineItem.
*/
const createFakeLineItem = (addr) => {
const beneficiaries = Array.iota(MAX_BENEFICIARIES_PER_ITEM).map((_) => Maybe(Object(Beneficiary)).Some(createFakeBeneficiary(addr)));
return createIsReal(false, {
totalCost: 0,
shipping: 0,
tax: 0,
beneficiaries
});
}
/**
* Array of order line items for a particular merchant.
*/
const Merchant = {
isReal: Bool,
addr: Address,
lineItems: Array(Maybe(Object(LineItem)), MAX_LINE_ITEMS_PER_MERCHANT)
}
/**
* Create a fake Merchants.
*
* @param addr
* The fake address.
* @returns
* The fake Merchants obj.
*/
const createFakeMerchants = (addr) => {
assert(addr !== null)
return createIsReal(false, {
addr,
lineItems: Array.iota(MAX_LINE_ITEMS_PER_MERCHANT).map(_ => Maybe(Object(LineItem)).Some(createFakeLineItem(addr)))
// lineItems: []
});
}
/**
* The order data for which payment is processed.
*/
const OrderData = {
orderTotal: UInt,
merchantItems: Array(Maybe(Object(Merchant)), MAX_TOTAL_MERCHANTS),
}
// ========================================================
// Laundromat
// ========================================================
/**
* Convert Array(Maybe(Object(Beneficiary)) to usable Array(Object(Beneficiary)).
*
* @param {Array(Maybe(Object(Beneficiary))} beneficiaries
* The array of maybe beneficiaries.
* @param addr
* The address to be used for the fakes.
* @returns {Array(Object(Beneficiary)}
* Array of usable beneficiaries.
*/
const cleanBeneficiaries = (beneficiaries, addr) => {
return beneficiaries.map((x) => {
return fromMaybe(x,
(() => createFakeBeneficiary(addr)),
((y) => createIsReal(true, y))
);
})
}
/**
* Convert Array(Maybe(Object(LineItem)) to usable Array(Object(LineItem)).
*
* @param {Array(Maybe(Object(LineItem))} lis
* The array of maybe line items..
* @param addr
* The address to be used for the fakes.
* @returns {Array(Object(LineItem)}
* Array of usable line items.
*/
const cleanLineItems = (lis, addr) => {
return lis.map((x) => {
return fromMaybe(x,
(() => createFakeLineItem(addr)),
((y) => createIsReal(true, y))
);
})
}
/**
* Convert Array(Maybe(Object(Merchant)) to usable Array(Object(Merchant)).
*
* @param {Array(Maybe(Object(Merchant))} m
* The array of maybe merchants.
* @param addr
* The address to be used for the fakes.
* @returns {Array(Object(Merchant)}
* Array of usable merchants.
*/
const cleanMerchants = (m, addr) => {
return m.map((x) => {
return fromMaybe(x,
(() => createFakeMerchants(addr)),
((y) => createIsReal(true, y))
);
})
}
/**
* Clean the entire orderData's tree.
*
* @param {OrderData} orderData
* The order data to be cleaned.
* @param {Address} fakesAddr
* The address to be used for fakes.
*
* @returns {OrderData}
* The cleaned OrderData.
*/
const cleanOrderData = (orderData, fakesAddr) => {
const merchantItemsClean = cleanMerchants(orderData.merchantItems, fakesAddr);
const merchantItemsFinal = merchantItemsClean.map(x => {
// Cleaning LineItems for single Merchant
const lineItemsClean = cleanLineItems(x.lineItems, fakesAddr);
const lineItemsFinal = lineItemsClean.map(y => {
// Cleaning Benficiaries for a single LineItem
const beneficiariesClean = cleanBeneficiaries(y.beneficiaries, fakesAddr);
return {
isReal: y.isReal,
totalCost: y.totalCost,
shipping: y.shipping,
tax: y.tax,
beneficiaries: beneficiariesClean
}
});
return {
isReal: x.isReal,
addr: x.addr,
lineItems: lineItemsFinal
}
});
return {
orderTotal: orderData.orderTotal,
merchantItems: merchantItemsFinal
}
}
// ========================================================
// Order Validation
// ========================================================
/**
* Check whether or not the order is valid to be processed.
*
* @todo Check that no merchants appear more than once.
*
* @param {OrderData} orderData
* The CLEANED order data. The logic assumes that all
* objects are operable, i.e. no Maybes.
*/
const validateCleanOrder = (orderData) => {
const positiveOrderTotal = orderData.orderTotal > 0;
const orderTotalCalcd = orderData.merchantItems.reduce(0, (oTotal, x) => {
const merchantTotal = x.lineItems.reduce(0, (mTotal, y) => mTotal + y.totalCost);
return oTotal + merchantTotal;
});
// Ensure that the provided order total matches the order contents.
const orderTotalsMatch = positiveOrderTotal == orderTotalCalcd;
// All amounts on the order must be >= 0.
const allAmtsNonNegative = orderData.merchantItems.reduce(true, (allAmtsPos, x) => {
const itemsPositive = x.lineItems.reduce(true, (ip, y) => {
const totalCostValid = y.isReal ? y.totalCost > 0 : y.totalCost == 0
const shippingValid = y.isReal ? y.shipping >= 0 : y.shipping == 0
const taxValid = y.isReal ? y.tax >= 0 : y.tax == 0
return !ip ? false : totalCostValid && shippingValid && taxValid
});
return !allAmtsPos ? false : itemsPositive;
});
// Any individual item's beneficiary percentages need to be <= 100.
const beneficiaryPctsValid = orderData.merchantItems.reduce(true, (pctsValid, x) => {
const itemPctsValid = x.lineItems.reduce(true, (itemPctValid, y) => {
const beneficiariesPct = y.beneficiaries.reduce(0, (pctTotal, z) => {
return pctTotal + z.percentToReceive;
});
return !itemPctValid ? false : beneficiariesPct <= 100;
});
return !pctsValid ? false : itemPctsValid;
});
// Any individual items' tax + shipping must be less than the order item's totalCost.
// If they exceed it then that means the total does not account for one of them.
const taxShippingValid = orderData.merchantItems.reduce(true, (tsValid, x) => {
const itemTsValid = x.lineItems.reduce(true, (itemTsValid, y) => {
return y.totalCost > y.tax + y.shipping;
});
return !tsValid ? false : itemTsValid;
});
const orderIsValid = orderTotalsMatch
&& allAmtsNonNegative
&& beneficiaryPctsValid
&& taxShippingValid;
return {
orderIsValid,
orderTotalsMatch,
allAmtsNonNegative,
beneficiaryPctsValid,
taxShippingValid
}
}
// ========================================================
// Participant Info
// ========================================================
/**
* Errors to present to the buyer on validation or other failure.
*/
const errors = {
// errorInvalidOrderTotal: Fun([], Null),
// errorAmountsExceedBalance: Fun([], Null),
// errorInvalidRecipientAmounts: Fun([], Null),
errorGenericInvalidOrder: Fun([], Null),
}
/**
* The Buyer Interface.
*/
const BuyerInterface = {
getOrderData: Fun([], Object(OrderData)),
// alertPaidRecipient: Fun([Address, UInt, Bytes], Null),
...errors,
};
// ========================================================
// Main Contract Logic
// ========================================================
export const main = Reach.App(
{}, [
ParticipantClass('Buyer', BuyerInterface),
Participant('Bakesale', {}),
],
(Buyer, Bakesale) => {
Bakesale.publish();
const keepGoing =
parallelReduce(true)
.invariant(balance() == balance())
.while(keepGoing)
.case(Buyer,
(() => {
const orderData = declassify(interact.getOrderData());
const orderDataClean = cleanOrderData(orderData, Bakesale);
const validationResult = validateCleanOrder(orderDataClean);
if(!validationResult.orderIsValid) {
interact.errorGenericInvalidOrder();
}
return {
when: validationResult.orderIsValid
}
}),
((_) => {
commit();
Buyer.only(() => {
const orderData = declassify(interact.getOrderData());
});
Buyer.publish(orderData);
const orderDataClean = cleanOrderData(orderData, Bakesale);
const validationResult = validateCleanOrder(orderDataClean);
// This should never happen since we validate in the
// local step above, but just in case.
if(!validationResult.orderIsValid) {
Buyer.only(() => declassify(interact.errorGenericInvalidOrder()));
return true;
} else {
commit();
Buyer.publish().pay(orderTotal);
// Keep this all simple for MVP testing.
// We can make the transfers more efficient
// and aggregated after we know it works.
orderDataClean.merchantItems.forEach(mi => {
// Looking at a single merchant.
if(mi.isReal) {
mi.lineItems.forEach(li => {
// Looking at a single line item.
if(li.isReal) {
const serviceFee = li.totalCost * BAKESALE_FEE_MULTIPLE;
const totalMinusFee = li.totalCost - serviceFee;
transfer(serviceFee).to(Bakesale);
// Buyer.interact(declassify(interact.alertPaidRecipient(Bakesale, serviceFee, 'service fee')))
/** @todo This needs to go to a tax acct. */
transfer(li.tax).to(Bakesale)
const pctToBeneficiaries = li.beneficiaries.reduce(0, (pct, x) => {
return pct + x.percentToReceive;
});
// Pay out the merchant.
const pctToMerchant = (100 - pctToBeneficiaries) / 100;
const amtToMerchant = pctToMerchant * totalMinusFee;
transfer(amtToMerchant).to(mi.addr);
// Pay out the beneficiaries
li.beneficiaries.forEach(ben => {
if(ben.isReal) {
const amtToBen = totalMinusFee * ben.percentToReceive;
transfer(amtToBen).to(ben);
}
})
}
})
}
});
assert(balace() == 0)
return true;
}
})
)
// Sufficiently long timeout that it will never be
// executed since the contract needs to be persistent.
.timeout(100^100, () => {
Anybody.publish();
return true;
});
if(balance() > 0) {
// Not sure how we'd ever end up with a balance here,
// but for now just transfer the remaining balance.
// We need to fix this so that it tracks the last buyer
// since it seems like they'd be the most likely source
// of these orphan funds?
transfer(balance()).to(Bakesale);
}
commit();
}
);
import {loadStdlib} from '@reach-sh/stdlib';
import * as backend from './build/index.main.mjs';
// Maximums allowed by the contract.
// This will exist in the final version.
const MAX_BENEFICIARIES_PER_ITEM = 5;
const MAX_LINE_ITEMS_PER_MERCHANT = 10;
const MAX_TOTAL_MERCHANTS = 5
// Used to generate the "real" objects that represent
// the order information passed in from the user's real
// cart/order interaction. These exist for TESTING ONLY
// and SHOULD NOT EXIST in the final version of the program
// as all values should be provided by checkout.
const REAL_BENFICIARIES_PER_ITEM_COUNT = 3
const FAKE_BENFICIARIES_PER_ITEM_COUNT = MAX_BENEFICIARIES_PER_ITEM - REAL_BENFICIARIES_PER_ITEM_COUNT;
const REAL_LINE_ITEMS_PER_MERCHANT_COUNT = 4
const FAKE_LINE_ITEMS_PER_MERCHANT_COUNT = MAX_LINE_ITEMS_PER_MERCHANT - REAL_LINE_ITEMS_PER_MERCHANT_COUNT;
const REAL_MERCHANTS_COUNT = 2;
const FAKE_MERCHANTS_COUNT = MAX_TOTAL_MERCHANTS - REAL_MERCHANTS_COUNT;
const PRICE_PER_LINE_ITEM = 20;
const TOTAL_PRICE_PER_MERCHANT = PRICE_PER_LINE_ITEM * REAL_LINE_ITEMS_PER_MERCHANT_COUNT;
const ORDER_TOTAL = TOTAL_PRICE_PER_MERCHANT * REAL_MERCHANTS_COUNT;
(async () => {
const stdlib = await loadStdlib();
const startingBalance = stdlib.parseCurrency(10000);
const createTestAcct = async () => {
await stdlib.newTestAccount(startingBalance)
}
const bakesale = await createTestAcct();
const ctcBakesale = bakesale.deploy(backend);
const ctcBakesaleInfo = ctcBakesale.getInfo();
const buyer = await createTestAcct();
const ctcBuyer = buyer.attach(backend, ctcBakesaleInfo);
const createRealBeneficiary = (addr, percentToReceive) => ({
isReal: true,
addr,
parentToReceive
});
const createRealLineItem = (totalCost, shipping, tax, beneficiaries) => ({
isReal: true,
totalCost,
shipping,
tax,
beneficiaries
});
const createRealMerchant = (addr, lineItems) => ({
isReal: true,
addr,
lineItems
});
const createOrderData = (orderTotal, Merchants) => ({
orderTotal, Merchants
});
const generateDummyOrderData = async () => {
const baseBeneficiaries = Promise.all (
Array.from(REAL_BENFICIARIES_PER_ITEM_COUNT).map(x => {
const acct = await createTestAcct();
const addr = acct.networkAccount;
const pct = 5;
return createRealBeneficiary(addr, pct)
})
).concat(
Array.from(FAKE_BENFICIARIES_PER_ITEM_COUNT).map(x => null)
);
const baseLineItems = Promise.all (
Array.from(REAL_LINE_ITEMS_PER_MERCHANT_COUNT).map(x => {
const totalPrice = stdlib.parseCurrency(PRICE_PER_LINE_ITEM)
return createRealLineItem(totalPrice, 0, 0, await baseBeneficiaries)
})
).concat(
Array.from(FAKE_LINE_ITEMS_PER_MERCHANT_COUNT).map(x => null)
);
const baseMerchants = Promise.all (
Array.from(REAL_MERCHANTS_COUNT).map(x => {
const acct = await createTestAcct();
const addr = acct.networkAccount;
return createRealMerchant(addr, await baseLineItems);
})
).concat(
Array.from(FAKE_MERCHANTS_COUNT).map(x => null)
);
const orderTotalParsed = stdlib.parseCurrency(ORDER_TOTAL);
return (async () => createOrderData(orderTotalParsed, await baseMerchants))();
};
await Promise.all([
backend.Bakesale(ctcBakesaleInfo, {}),
backend.Buyer(ctcBuyer, {
orderData: async () => {
return await generateDummyOrderData();
},
errorGenericInvalidOrder: () => {
console.log('Order was not processed due to an error.')
},
// alertPaidRecipient: (addr, amt, reason) => {
// console.log(`Buyer paid ${amt} to ${addr} for ${reason}.`)
// }
}),
]);
})();
When running make run-all
after downloading the repository, the RPS test appears to have hung. No new output occurred for around a minute and so I terminated the process and reran the make run-all
script. The second time, RPS ran correctly without any delay around this step.
Below is the segment of the log that occurred before the hang.
Running game that times out
Alice initiates a new game.
Alice publishes parameters of game: wager of 1.5ETH and escrow of 0.15ETH.
Bob accepts the terms: wager of 1500000000000000000WEI and escrow of 150000000000000000WEI.
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
(local: Alice plays SCISSORS.)
Alice commits to play with (hidden) hand.
Below is the output from that same segment in the second run which succeeded.
Alice initiates a new game.
Alice publishes parameters of game: wager of 1.5ETH and escrow of 0.15ETH.
Bob accepts the terms: wager of 1500000000000000000WEI and escrow of 150000000000000000WEI.
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
Alice takes her sweet time...
(local: Alice plays PAPER.)
Alice commits to play with (hidden) hand.
Alice thinks outcome is Alice quits.
Bob thinks outcome is Alice quits.
Observer thinks outcome is Alice quits.
Done!
The following report includes the exact steps I took to reach an error as well as the error log I received. Unfortunately I wasn't able to recreate the error, so the steps are a bit convoluted.
Initially the multisig example failed when running make run-all
with the attached error. Running make run-all
a second time led to the same error. After this failed, I tried running make run
inside the multisig folder which succeeded. I then tried running make run-all
again which also succeeded. After deleting and re-cloning the repository, the multisig example still worked properly. My best guess is that there's something locally cached from the multisig build, but I can't recreate the initial issue.
Successfully tagged reachsh/examples-multisig:v0.1.1
WARNING: Image for service reach-app was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
{"jsonrpc":"2.0","id":67,"result":"Geth/v1.9.2-stable-e76047e9/linux-amd64/go1.12.7"}
> @reach-sh/[email protected] pretest /app
> eslint --ignore-path .gitignore --ext .mjs .
> @reach-sh/[email protected] test /app
> node --experimental-modules index.mjs
(node:31) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/esm/default_resolve.js:59
let url = moduleWrapResolve(specifier, parentURL);
^
Error: Cannot find module /app/build/multisig.mjs imported from /app/index.mjs
at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:59:13)
at Loader.resolve (internal/modules/esm/loader.js:73:33)
at Loader.getModuleJob (internal/modules/esm/loader.js:149:40)
at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:43:40)
at link (internal/modules/esm/module_job.js:42:36) {
code: 'ERR_MODULE_NOT_FOUND'
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @reach-sh/[email protected] test: `node --experimental-modules index.mjs`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @reach-sh/[email protected] 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! /root/.npm/_logs/2020-03-18T20_31_50_712Z-debug.log
make[1]: *** [run] Error 1
make: *** [run-all] Error 2
The parallelReduce loop works correctly for the first visit of ParticipantClass Giver who pays, sets when=false
, and calls interact.stopWatching
which calls process.exit(0)
. For subsequent visits, the parallelReduce loop seems to ignore declassify
, and, instead, uses the declassified data from the first visit. Here is index.rsh. Glad to provide more data or a demo.
'reach 0.1';
const CommonAPI = {
reportProjectName: Fun([Bytes(64)], Null),
reportContractBalance: Fun([UInt], Null),
reportTimeout: Fun([], Null),
stopWatching: Fun([], Null)
}
const ReceiverAPI = {
...CommonAPI,
projectName: Bytes(64),
projectGoal: UInt,
projectDuration: UInt
};
const GiverAPI = {
...CommonAPI,
getGift: Fun([], UInt),
askToGive: Fun([], Bool),
reportPayment: Fun([UInt], Null),
reportDone: Fun([], Null)
};
export const main = Reach.App(() => {
const R = Participant('Receiver', ReceiverAPI);
const G = ParticipantClass('Giver', GiverAPI);
deploy();
R.only(() => {
const p = {
name: declassify(interact.projectName),
goal: declassify(interact.projectGoal),
duration: declassify(interact.projectDuration)
}
});
R.publish(p);
R.interact.stopWatching();
const [inLoop, sum] = parallelReduce([true, 0])
.invariant(balance() == sum)
.while(inLoop && balance() < p.goal)
.case(
G,
(() => {
const shouldGive = declassify(interact.askToGive());
if (!shouldGive) { interact.stopWatching(); }
return { when: shouldGive, msg: declassify(interact.getGift()) }
}),
((gift) => gift),
((gift) => {
G.only(() => {
interact.reportPayment(gift);
interact.reportContractBalance(balance());
});
return [true, balance()];
})
)
.timeout(p.duration, () => {
G.interact.reportTimeout();
Anybody.publish();
return [false, sum];
});
transfer(balance()).to(R);
commit();
G.interact.reportDone();
exit();
});
https://docs.reach.sh/ref-programs-consensus.html#%28reach._%28%28parallel.Reduce%29%29%29
5.4.6.1.7 parallelReduce section
'ParalleReduce([ true, Funder, 0 ])'
'ParalleReduce([ true, Funder, 0 ])'
2) Some explaination of how function .Case() works and expecting which parameters as inputs
The error seems to be cause by Webpack 5 not being able to resolve the imports within a .mjs file.
Related issue: webpack/webpack#11467
Attempted suggested solution with no success: webpack/webpack#11467 (comment)
Webpack Config File
/* eslint-disable */
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
require('dotenv').config()
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
publicPath: '/'
},
devServer: {
port: process.env.DEV_PORT,
watchContentBase: true
},
resolve: {
extensions: ['.js', '.ts', '.mjs', '.json', '.wasm']
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader', 'eslint-loader']
},
{
test: /\.m?js/,
resolve: {
fullySpecified: false
}
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
},
]
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' }),
new MiniCssExtractPlugin()
],
}
Error message:
vsh in ~/Documents/github/crypto/algorand/reach/battleship/client(ruby-3.0.0) on master λ npm run nodeserve
> [email protected] nodeserve
> node server.js
Battleship client development server running on port 3000...
✖ 「wdm」: assets by chunk 3.39 MiB (name: index)
asset index.bundle.js 3.39 MiB [emitted] (name: index)
asset index.css 21 bytes [emitted] (name: index)
asset 10fe4030c4f3a48a7c95.png 6.42 KiB [emitted] [immutable] [from: src/assets/battleship.png] (auxiliary name: index)
asset index.html 376 bytes [emitted]
Entrypoint index 3.39 MiB (6.42 KiB) = index.css 21 bytes index.bundle.js 3.39 MiB 1 auxiliary asset
orphan modules 2.27 KiB [orphan] 8 modules
runtime modules 1.31 KiB 8 modules
modules by path ./node_modules/ 2.93 MiB 265 modules
modules by path ./src/ 4.41 KiB (javascript) 6.42 KiB (asset) 20 bytes (css/mini-extract)
javascript modules 4.31 KiB
./src/index.js 252 bytes [built] [code generated] [1 warning]
./src/App.js 4.02 KiB [built] [code generated] [1 warning]
./src/App.css 50 bytes [built] [code generated]
modules by path ./src/assets/ 99 bytes (javascript) 6.42 KiB (asset)
./src/assets/battleship.png 42 bytes (javascript) 6.42 KiB (asset) [built] [code generated]
./src/assets/game-description.json 57 bytes [built] [code generated]
css ./node_modules/css-loader/dist/cjs.js!./src/App.css 20 bytes [code generated]
buffer (ignored) 15 bytes [optional] [built] [code generated]
crypto (ignored) 15 bytes [built] [code generated]
./util.inspect (ignored) 15 bytes [built] [code generated]
WARNING in ./src/App.js
Module Warning (from ./node_modules/eslint-loader/dist/cjs.js):
/Users/vsh/Documents/github/crypto/algorand/reach/battleship/client/src/App.js
6:8 warning Missing space before function parentheses space-before-function-paren
15:9 warning Missing space before function parentheses space-before-function-paren
✖ 2 problems (0 errors, 2 warnings)
0 errors and 2 warnings potentially fixable with the `--fix` option.
@ ./src/index.js 4:0-24 6:50-53
WARNING in ./src/index.js
Module Warning (from ./node_modules/eslint-loader/dist/cjs.js):
/Users/vsh/Documents/github/crypto/algorand/reach/battleship/client/src/index.js
1:8 warning 'React' is defined but never used no-unused-vars
3:13 warning 'reach' is defined but never used no-unused-vars
4:8 warning 'App' is defined but never used no-unused-vars
✖ 3 problems (0 errors, 3 warnings)
ERROR in ./node_modules/@reach-sh/stdlib/ALGO.mjs 582:10-24
export 'default' (imported as 'msgpack') was not found in '@msgpack/msgpack' (possible exports: DataViewIndexOutOfBoundsError, DecodeError, Decoder, EXT_TIMESTAMP, Encoder, ExtData, ExtensionCodec, decode, decodeArrayStream, decodeAsync, decodeMulti, decodeMultiStream, decodeStream, decodeTimestampExtension, decodeTimestampToTimeSpec, encode, encodeDateToTimeSpec, encodeTimeSpecToTimestamp, encodeTimestampExtension)
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO.mjs 613:10-24
export 'default' (imported as 'msgpack') was not found in '@msgpack/msgpack' (possible exports: DataViewIndexOutOfBoundsError, DecodeError, Decoder, EXT_TIMESTAMP, Encoder, ExtData, ExtensionCodec, decode, decodeArrayStream, decodeAsync, decodeMulti, decodeMultiStream, decodeStream, decodeTimestampExtension, decodeTimestampToTimeSpec, encode, encodeDateToTimeSpec, encodeTimeSpecToTimestamp, encodeTimestampExtension)
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO.mjs 895:17-38
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO.mjs 1140:13-34
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO_compiled.mjs 11:18-34
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 17:0-103 19:43-57 373:46-60 374:127-135 643:9-21 927:51-65 978:94-108 1022:28-42 1035:76-90 1233:9-23 1235:27-41
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO_compiled.mjs 30:18-38
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 17:0-103 19:43-57 373:46-60 374:127-135 643:9-21 927:51-65 978:94-108 1022:28-42 1035:76-90 1233:9-23 1235:27-41
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO_compiled.mjs 30:39-60
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 17:0-103 19:43-57 373:46-60 374:127-135 643:9-21 927:51-65 978:94-108 1022:28-42 1035:76-90 1233:9-23 1235:27-41
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO_compiled.mjs 34:11-32
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 17:0-103 19:43-57 373:46-60 374:127-135 643:9-21 927:51-65 978:94-108 1022:28-42 1035:76-90 1233:9-23 1235:27-41
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO_compiled.mjs 39:18-42
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 17:0-103 19:43-57 373:46-60 374:127-135 643:9-21 927:51-65 978:94-108 1022:28-42 1035:76-90 1233:9-23 1235:27-41
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO_compiled.mjs 40:20-45
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 17:0-103 19:43-57 373:46-60 374:127-135 643:9-21 927:51-65 978:94-108 1022:28-42 1035:76-90 1233:9-23 1235:27-41
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO_compiled.mjs 44:18-39
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 17:0-103 19:43-57 373:46-60 374:127-135 643:9-21 927:51-65 978:94-108 1022:28-42 1035:76-90 1233:9-23 1235:27-41
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO_compiled.mjs 45:20-40
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 17:0-103 19:43-57 373:46-60 374:127-135 643:9-21 927:51-65 978:94-108 1022:28-42 1035:76-90 1233:9-23 1235:27-41
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO_compiled.mjs 81:11-30
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 17:0-103 19:43-57 373:46-60 374:127-135 643:9-21 927:51-65 978:94-108 1022:28-42 1035:76-90 1233:9-23 1235:27-41
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO_compiled.mjs 99:11-30
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 17:0-103 19:43-57 373:46-60 374:127-135 643:9-21 927:51-65 978:94-108 1022:28-42 1035:76-90 1233:9-23 1235:27-41
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO_compiled.mjs 118:11-30
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 17:0-103 19:43-57 373:46-60 374:127-135 643:9-21 927:51-65 978:94-108 1022:28-42 1035:76-90 1233:9-23 1235:27-41
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO_compiled.mjs 141:13-32
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 17:0-103 19:43-57 373:46-60 374:127-135 643:9-21 927:51-65 978:94-108 1022:28-42 1035:76-90 1233:9-23 1235:27-41
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/ALGO_compiled.mjs 175:13-32
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 17:0-103 19:43-57 373:46-60 374:127-135 643:9-21 927:51-65 978:94-108 1022:28-42 1035:76-90 1233:9-23 1235:27-41
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/CBR.mjs 2:18-34
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/shared.mjs 3:0-60 5:0-43 5:0-43 110:13-25 138:37-49 143:15-27 161:28-40 161:47-59 164:30-42 164:50-62 165:30-42 165:50-62 166:30-42 166:50-62 167:30-42 167:50-62 168:30-42 168:50-62 171:28-40 171:48-60 172:28-40 172:47-59 173:28-40 173:48-60 174:28-40 174:47-59 199:77-89 200:31-43
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 14:0-168 20:0-29 20:0-29 80:6-11 84:4-9 92:2-7 102:2-7 112:4-9 122:2-7 125:4-9 129:4-9 298:77-89 301:4-9 351:2-7 358:2-7 375:41-51 396:2-7 400:2-7 479:22-32 483:30-40 548:45-55 557:17-34 559:102-119 566:18-30 580:4-9 581:4-9 582:4-9 602:4-9 604:4-9 605:4-9 611:4-9 612:4-9 613:4-9 624:2-7 640:4-9 649:33-45 665:6-11 670:25-34 671:33-42 675:14-26 685:6-11 689:6-11 695:6-11 701:10-15 703:12-17 707:8-13 712:20-32 737:12-18 748:8-13 749:8-14 752:92-104 754:8-13 766:8-13 768:8-13 775:8-13 777:8-13 800:10-15 812:8-13 817:10-15 820:12-17 822:12-17 846:6-11 875:8-13 886:8-13 888:8-13 894:10-15 897:8-13 900:8-13 901:24-33 902:8-13 905:8-13 908:8-13 911:8-13 920:16-28 926:37-49 929:6-11 936:8-13 943:8-13 945:8-13 947:8-13 949:8-13 957:17-34 958:6-11 960:6-11 965:6-11 967:6-11 970:8-13 973:8-13 977:21-35 982:4-9 1019:4-9 1024:11-24 1027:11-24 1043:9-21 1069:21-32 1072:9-21 1076:30-42 1093:23-35 1108:6-11 1111:6-11 1158:42-54 1163:4-9 1165:18-30 1168:2-7 1173:2-7 1194:2-7 1204:6-11 1210:2-7
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/CBR.mjs 32:18-39
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/shared.mjs 3:0-60 5:0-43 5:0-43 110:13-25 138:37-49 143:15-27 161:28-40 161:47-59 164:30-42 164:50-62 165:30-42 165:50-62 166:30-42 166:50-62 167:30-42 167:50-62 168:30-42 168:50-62 171:28-40 171:48-60 172:28-40 172:47-59 173:28-40 173:48-60 174:28-40 174:47-59 199:77-89 200:31-43
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 14:0-168 20:0-29 20:0-29 80:6-11 84:4-9 92:2-7 102:2-7 112:4-9 122:2-7 125:4-9 129:4-9 298:77-89 301:4-9 351:2-7 358:2-7 375:41-51 396:2-7 400:2-7 479:22-32 483:30-40 548:45-55 557:17-34 559:102-119 566:18-30 580:4-9 581:4-9 582:4-9 602:4-9 604:4-9 605:4-9 611:4-9 612:4-9 613:4-9 624:2-7 640:4-9 649:33-45 665:6-11 670:25-34 671:33-42 675:14-26 685:6-11 689:6-11 695:6-11 701:10-15 703:12-17 707:8-13 712:20-32 737:12-18 748:8-13 749:8-14 752:92-104 754:8-13 766:8-13 768:8-13 775:8-13 777:8-13 800:10-15 812:8-13 817:10-15 820:12-17 822:12-17 846:6-11 875:8-13 886:8-13 888:8-13 894:10-15 897:8-13 900:8-13 901:24-33 902:8-13 905:8-13 908:8-13 911:8-13 920:16-28 926:37-49 929:6-11 936:8-13 943:8-13 945:8-13 947:8-13 949:8-13 957:17-34 958:6-11 960:6-11 965:6-11 967:6-11 970:8-13 973:8-13 977:21-35 982:4-9 1019:4-9 1024:11-24 1027:11-24 1043:9-21 1069:21-32 1072:9-21 1076:30-42 1093:23-35 1108:6-11 1111:6-11 1158:42-54 1163:4-9 1165:18-30 1168:2-7 1173:2-7 1194:2-7 1204:6-11 1210:2-7
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/CBR.mjs 88:16-40
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/shared.mjs 3:0-60 5:0-43 5:0-43 110:13-25 138:37-49 143:15-27 161:28-40 161:47-59 164:30-42 164:50-62 165:30-42 165:50-62 166:30-42 166:50-62 167:30-42 167:50-62 168:30-42 168:50-62 171:28-40 171:48-60 172:28-40 172:47-59 173:28-40 173:48-60 174:28-40 174:47-59 199:77-89 200:31-43
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 14:0-168 20:0-29 20:0-29 80:6-11 84:4-9 92:2-7 102:2-7 112:4-9 122:2-7 125:4-9 129:4-9 298:77-89 301:4-9 351:2-7 358:2-7 375:41-51 396:2-7 400:2-7 479:22-32 483:30-40 548:45-55 557:17-34 559:102-119 566:18-30 580:4-9 581:4-9 582:4-9 602:4-9 604:4-9 605:4-9 611:4-9 612:4-9 613:4-9 624:2-7 640:4-9 649:33-45 665:6-11 670:25-34 671:33-42 675:14-26 685:6-11 689:6-11 695:6-11 701:10-15 703:12-17 707:8-13 712:20-32 737:12-18 748:8-13 749:8-14 752:92-104 754:8-13 766:8-13 768:8-13 775:8-13 777:8-13 800:10-15 812:8-13 817:10-15 820:12-17 822:12-17 846:6-11 875:8-13 886:8-13 888:8-13 894:10-15 897:8-13 900:8-13 901:24-33 902:8-13 905:8-13 908:8-13 911:8-13 920:16-28 926:37-49 929:6-11 936:8-13 943:8-13 945:8-13 947:8-13 949:8-13 957:17-34 958:6-11 960:6-11 965:6-11 967:6-11 970:8-13 973:8-13 977:21-35 982:4-9 1019:4-9 1024:11-24 1027:11-24 1043:9-21 1069:21-32 1072:9-21 1076:30-42 1093:23-35 1108:6-11 1111:6-11 1158:42-54 1163:4-9 1165:18-30 1168:2-7 1173:2-7 1194:2-7 1204:6-11 1210:2-7
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/shared.mjs 1:0-28
Module not found: Error: Can't resolve 'crypto' in '/Users/vsh/Documents/github/crypto/algorand/reach/battleship/client/node_modules/@reach-sh/stdlib'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "crypto": false }
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 14:0-168 20:0-29 20:0-29 80:6-11 84:4-9 92:2-7 102:2-7 112:4-9 122:2-7 125:4-9 129:4-9 298:77-89 301:4-9 351:2-7 358:2-7 375:41-51 396:2-7 400:2-7 479:22-32 483:30-40 548:45-55 557:17-34 559:102-119 566:18-30 580:4-9 581:4-9 582:4-9 602:4-9 604:4-9 605:4-9 611:4-9 612:4-9 613:4-9 624:2-7 640:4-9 649:33-45 665:6-11 670:25-34 671:33-42 675:14-26 685:6-11 689:6-11 695:6-11 701:10-15 703:12-17 707:8-13 712:20-32 737:12-18 748:8-13 749:8-14 752:92-104 754:8-13 766:8-13 768:8-13 775:8-13 777:8-13 800:10-15 812:8-13 817:10-15 820:12-17 822:12-17 846:6-11 875:8-13 886:8-13 888:8-13 894:10-15 897:8-13 900:8-13 901:24-33 902:8-13 905:8-13 908:8-13 911:8-13 920:16-28 926:37-49 929:6-11 936:8-13 943:8-13 945:8-13 947:8-13 949:8-13 957:17-34 958:6-11 960:6-11 965:6-11 967:6-11 970:8-13 973:8-13 977:21-35 982:4-9 1019:4-9 1024:11-24 1027:11-24 1043:9-21 1069:21-32 1072:9-21 1076:30-42 1093:23-35 1108:6-11 1111:6-11 1158:42-54 1163:4-9 1165:18-30 1168:2-7 1173:2-7 1194:2-7 1204:6-11 1210:2-7
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/shared.mjs 4:0-24
Module not found: Error: Can't resolve 'util' in '/Users/vsh/Documents/github/crypto/algorand/reach/battleship/client/node_modules/@reach-sh/stdlib'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
- install 'util'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "util": false }
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 14:0-168 20:0-29 20:0-29 80:6-11 84:4-9 92:2-7 102:2-7 112:4-9 122:2-7 125:4-9 129:4-9 298:77-89 301:4-9 351:2-7 358:2-7 375:41-51 396:2-7 400:2-7 479:22-32 483:30-40 548:45-55 557:17-34 559:102-119 566:18-30 580:4-9 581:4-9 582:4-9 602:4-9 604:4-9 605:4-9 611:4-9 612:4-9 613:4-9 624:2-7 640:4-9 649:33-45 665:6-11 670:25-34 671:33-42 675:14-26 685:6-11 689:6-11 695:6-11 701:10-15 703:12-17 707:8-13 712:20-32 737:12-18 748:8-13 749:8-14 752:92-104 754:8-13 766:8-13 768:8-13 775:8-13 777:8-13 800:10-15 812:8-13 817:10-15 820:12-17 822:12-17 846:6-11 875:8-13 886:8-13 888:8-13 894:10-15 897:8-13 900:8-13 901:24-33 902:8-13 905:8-13 908:8-13 911:8-13 920:16-28 926:37-49 929:6-11 936:8-13 943:8-13 945:8-13 947:8-13 949:8-13 957:17-34 958:6-11 960:6-11 965:6-11 967:6-11 970:8-13 973:8-13 977:21-35 982:4-9 1019:4-9 1024:11-24 1027:11-24 1043:9-21 1069:21-32 1072:9-21 1076:30-42 1093:23-35 1108:6-11 1111:6-11 1158:42-54 1163:4-9 1165:18-30 1168:2-7 1173:2-7 1194:2-7 1204:6-11 1210:2-7
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/shared.mjs 64:60-72
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 14:0-168 20:0-29 20:0-29 80:6-11 84:4-9 92:2-7 102:2-7 112:4-9 122:2-7 125:4-9 129:4-9 298:77-89 301:4-9 351:2-7 358:2-7 375:41-51 396:2-7 400:2-7 479:22-32 483:30-40 548:45-55 557:17-34 559:102-119 566:18-30 580:4-9 581:4-9 582:4-9 602:4-9 604:4-9 605:4-9 611:4-9 612:4-9 613:4-9 624:2-7 640:4-9 649:33-45 665:6-11 670:25-34 671:33-42 675:14-26 685:6-11 689:6-11 695:6-11 701:10-15 703:12-17 707:8-13 712:20-32 737:12-18 748:8-13 749:8-14 752:92-104 754:8-13 766:8-13 768:8-13 775:8-13 777:8-13 800:10-15 812:8-13 817:10-15 820:12-17 822:12-17 846:6-11 875:8-13 886:8-13 888:8-13 894:10-15 897:8-13 900:8-13 901:24-33 902:8-13 905:8-13 908:8-13 911:8-13 920:16-28 926:37-49 929:6-11 936:8-13 943:8-13 945:8-13 947:8-13 949:8-13 957:17-34 958:6-11 960:6-11 965:6-11 967:6-11 970:8-13 973:8-13 977:21-35 982:4-9 1019:4-9 1024:11-24 1027:11-24 1043:9-21 1069:21-32 1072:9-21 1076:30-42 1093:23-35 1108:6-11 1111:6-11 1158:42-54 1163:4-9 1165:18-30 1168:2-7 1173:2-7 1194:2-7 1204:6-11 1210:2-7
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/shared.mjs 65:18-34
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 14:0-168 20:0-29 20:0-29 80:6-11 84:4-9 92:2-7 102:2-7 112:4-9 122:2-7 125:4-9 129:4-9 298:77-89 301:4-9 351:2-7 358:2-7 375:41-51 396:2-7 400:2-7 479:22-32 483:30-40 548:45-55 557:17-34 559:102-119 566:18-30 580:4-9 581:4-9 582:4-9 602:4-9 604:4-9 605:4-9 611:4-9 612:4-9 613:4-9 624:2-7 640:4-9 649:33-45 665:6-11 670:25-34 671:33-42 675:14-26 685:6-11 689:6-11 695:6-11 701:10-15 703:12-17 707:8-13 712:20-32 737:12-18 748:8-13 749:8-14 752:92-104 754:8-13 766:8-13 768:8-13 775:8-13 777:8-13 800:10-15 812:8-13 817:10-15 820:12-17 822:12-17 846:6-11 875:8-13 886:8-13 888:8-13 894:10-15 897:8-13 900:8-13 901:24-33 902:8-13 905:8-13 908:8-13 911:8-13 920:16-28 926:37-49 929:6-11 936:8-13 943:8-13 945:8-13 947:8-13 949:8-13 957:17-34 958:6-11 960:6-11 965:6-11 967:6-11 970:8-13 973:8-13 977:21-35 982:4-9 1019:4-9 1024:11-24 1027:11-24 1043:9-21 1069:21-32 1072:9-21 1076:30-42 1093:23-35 1108:6-11 1111:6-11 1158:42-54 1163:4-9 1165:18-30 1168:2-7 1173:2-7 1194:2-7 1204:6-11 1210:2-7
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/shared.mjs 134:12-34
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 14:0-168 20:0-29 20:0-29 80:6-11 84:4-9 92:2-7 102:2-7 112:4-9 122:2-7 125:4-9 129:4-9 298:77-89 301:4-9 351:2-7 358:2-7 375:41-51 396:2-7 400:2-7 479:22-32 483:30-40 548:45-55 557:17-34 559:102-119 566:18-30 580:4-9 581:4-9 582:4-9 602:4-9 604:4-9 605:4-9 611:4-9 612:4-9 613:4-9 624:2-7 640:4-9 649:33-45 665:6-11 670:25-34 671:33-42 675:14-26 685:6-11 689:6-11 695:6-11 701:10-15 703:12-17 707:8-13 712:20-32 737:12-18 748:8-13 749:8-14 752:92-104 754:8-13 766:8-13 768:8-13 775:8-13 777:8-13 800:10-15 812:8-13 817:10-15 820:12-17 822:12-17 846:6-11 875:8-13 886:8-13 888:8-13 894:10-15 897:8-13 900:8-13 901:24-33 902:8-13 905:8-13 908:8-13 911:8-13 920:16-28 926:37-49 929:6-11 936:8-13 943:8-13 945:8-13 947:8-13 949:8-13 957:17-34 958:6-11 960:6-11 965:6-11 967:6-11 970:8-13 973:8-13 977:21-35 982:4-9 1019:4-9 1024:11-24 1027:11-24 1043:9-21 1069:21-32 1072:9-21 1076:30-42 1093:23-35 1108:6-11 1111:6-11 1158:42-54 1163:4-9 1165:18-30 1168:2-7 1173:2-7 1194:2-7 1204:6-11 1210:2-7
@ ./src/index.js 3:0-51
ERROR in ./node_modules/@reach-sh/stdlib/shared.mjs 145:15-38
export 'default' (imported as 'ethers') was not found in 'ethers' (possible exports: BaseContract, BigNumber, Contract, ContractFactory, FixedNumber, Signer, VoidSigner, Wallet, Wordlist, constants, errors, ethers, getDefaultProvider, logger, providers, utils, version, wordlists)
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 14:0-168 20:0-29 20:0-29 80:6-11 84:4-9 92:2-7 102:2-7 112:4-9 122:2-7 125:4-9 129:4-9 298:77-89 301:4-9 351:2-7 358:2-7 375:41-51 396:2-7 400:2-7 479:22-32 483:30-40 548:45-55 557:17-34 559:102-119 566:18-30 580:4-9 581:4-9 582:4-9 602:4-9 604:4-9 605:4-9 611:4-9 612:4-9 613:4-9 624:2-7 640:4-9 649:33-45 665:6-11 670:25-34 671:33-42 675:14-26 685:6-11 689:6-11 695:6-11 701:10-15 703:12-17 707:8-13 712:20-32 737:12-18 748:8-13 749:8-14 752:92-104 754:8-13 766:8-13 768:8-13 775:8-13 777:8-13 800:10-15 812:8-13 817:10-15 820:12-17 822:12-17 846:6-11 875:8-13 886:8-13 888:8-13 894:10-15 897:8-13 900:8-13 901:24-33 902:8-13 905:8-13 908:8-13 911:8-13 920:16-28 926:37-49 929:6-11 936:8-13 943:8-13 945:8-13 947:8-13 949:8-13 957:17-34 958:6-11 960:6-11 965:6-11 967:6-11 970:8-13 973:8-13 977:21-35 982:4-9 1019:4-9 1024:11-24 1027:11-24 1043:9-21 1069:21-32 1072:9-21 1076:30-42 1093:23-35 1108:6-11 1111:6-11 1158:42-54 1163:4-9 1165:18-30 1168:2-7 1173:2-7 1194:2-7 1204:6-11 1210:2-7
@ ./src/index.js 3:0-51
ERROR in ./node_modules/wait-port/lib/wait-port.js 2:12-26
Module not found: Error: Can't resolve 'net' in '/Users/vsh/Documents/github/crypto/algorand/reach/battleship/client/node_modules/wait-port/lib'
@ ./node_modules/@reach-sh/stdlib/waitPort.mjs 1:0-36 22:8-19
@ ./node_modules/@reach-sh/stdlib/ALGO.mjs 15:0-38 34:15-23
@ ./src/index.js 3:0-51
3 errors have detailed information that is not shown.
Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it.
webpack 5.37.1 compiled with 27 errors and 2 warnings in 2333 ms
ℹ 「wdm」: Failed to compile.
See this video to watch a parallelReduce test that passes on Algorand and fails on Ethereum. Video includes tests specs, link to github repo, and error msg at the end. I'll show the error msg here, too:
/stdlib/node_modules/@ethersproject/logger/lib/index.js:187
var error = new Error(message);
^
Error: missing response (requestBody="{\"method\":\"eth_blockNumber\",\"params\":[],\"id\":94,\"jsonrpc\":\"2.0\"}", requestMethod="POST", serverError={"code":"ECONNRESET"}, url="http://ethereum-devnet:8545", code=SERVER_ERROR, version=web/5.3.0)
at Logger.makeError (/stdlib/node_modules/@ethersproject/logger/lib/index.js:187:21)
at Logger.throwError (/stdlib/node_modules/@ethersproject/logger/lib/index.js:196:20)
at /stdlib/node_modules/@ethersproject/web/lib/index.js:213:36
at step (/stdlib/node_modules/@ethersproject/web/lib/index.js:33:23)
at Object.throw (/stdlib/node_modules/@ethersproject/web/lib/index.js:14:53)
at rejected (/stdlib/node_modules/@ethersproject/web/lib/index.js:6:65)
at processTicksAndRejections (internal/process/task_queues.js:95:5) {
reason: 'missing response',
code: 'SERVER_ERROR',
requestBody: '{"method":"eth_blockNumber","params":[],"id":94,"jsonrpc":"2.0"}',
requestMethod: 'POST',
serverError: Error: socket hang up
at connResetException (internal/errors.js:607:14)
at Socket.socketOnEnd (_http_client.js:499:23)
at Socket.emit (events.js:388:22)
at endReadableNT (internal/streams/readable.js:1336:12)
at processTicksAndRejections (internal/process/task_queues.js:82:21) {
code: 'ECONNRESET'
},
url: 'http://ethereum-devnet:8545'
I followed basic steps in https://docs.reach.sh/tut-2.html after running reach run
I get the following set of logs:
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
make: *** [build/index.main.mjs] Error 137
OS Version : macOS Big Sur 11.4
Chip: Apple M1
Would appreciate any feedback input on this, I suspect it has something to do with the M1 chip itself, running identical set of steps on an intel based Mac works without any issues. Thanks in advance for any replies!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.