In this tutorial we will walk you through building a cartesi machine that you publish from scratch. We'll also show what it looks for a user to download the machine and run it. This mirrors a bit https://www.cartesi.io/en/docs/tutorials/calculator/cartesi-machine/. For full details on the why and interworkings of Cartesi the tutorial linked above, is immensely helpful. This will focus on using Carti.
#Carti npm install -g @createdreamtech/carti # Probably docker if you want to run the end results
git clone git@github.com:createdreamtech/carti-sample.git cd carti-sample
carti machine install --global https://raw.githubusercontent.com/createdreamtech/carti-default/main/carti-machine-package.json --nobundle --nobuild carti machine init cat carti-machine-package.json
Here we will be creating a custom flash drive, that will house a calculation
# Pop into docker so we produce these under a consistent environment docker run -e USER=$(id -u -n) -e UID=$(id -u) -e GID=$(id -g) -e GROUP=$(id -g -n) \ -v $(pwd):/opt/carti -it cartesi/playground /bin/bash # Our future input flash drive echo "2^71 + 36^12" > input.raw # size it up to be on a 4K size interval as required by the cartesi machines truncate -s 4K input.raw truncate -s 4K output.raw
The first thing we need to do once we have the drive is bundle it so we can use it as well as other people
carti bundle -t flashdrive -n calculator-input -v 0.0.1 -d "calculator input" ./input.raw # outputs bundled: calculator-input as baenrwigmw66wmp2vwjejrmmlw5sbvwpsx3zjtnd7rep4oo6wd3glahtfl4 carti bundle -t flashdrive -n calculator-output -v 0.0.1 -d "calculator output" ./output.raw # outputs bundled: calculator-output as baenrwia5pfe7b6dvoys33k7umgsbbixgpympwcfjpqowpaye3bghmrs24m
The result should look like
. ├── LICENSE ├── README.md ├── carti-machine-package.json ├── carti_bundles │ ├── baenrwia5pfe7b6dvoys33k7umgsbbixgpympwcfjpqowpaye3bghmrs24m │ │ ├── carti-meta.json │ │ └── output.raw │ └── baenrwigmw66wmp2vwjejrmmlw5sbvwpsx3zjtnd7rep4oo6wd3glahtfl4 │ ├── carti-meta.json │ └── input.raw ├── input.raw └── output.raw
We created a carti_bundles/ directory this functions as a local store for any data that you've bundle up The recommendation is that carti_bundles/ not be uploaded to git.
echo "carti_bundles/" >> .gitignore
What do we have installed?
carti list
We have the following bundles installed:
@flashdrive/calculator-input:0.0.1:baenrwigmw66wmp2vwjejrmmlw5sbvwpsx3zjtnd7rep4oo6wd3glahtfl4:local @flashdrive/calculator-output:0.0.1:baenrwia5pfe7b6dvoys33k7umgsbbixgpympwcfjpqowpaye3bghmrs24m:local @rom/default-rom:v0.4.0:baenrwigwdfweve3apyvwicc2zpmzz6vdhsg62xnmzhauruw6ud4dbbafuq:global @ram/default-ram:v0.7.0:baenrwia5vqqvdu5chzjqq57tfo45z2txorpnmljeiuwemcibba43noqpvu:global @flash/default-root:v0.6.0:baenrwig2hfjzzeqmozb7sws6tyxmyazvuipjp5hxamtllifsokwh73eucy:global
There are many ways to make a bundle accessible, disk, s3, or other We're going to use other, because it's just a flexible way for us to link data. so let's use github
carti publish uri calculator-input https://github.com/createdreamtech/carti-sample/blob/feat/complete/input.raw carti publish uri calculator-output https://github.com/createdreamtech/carti-sample/blob/feat/complete/output.raw cat bundles.json
So bundles.json provides a way for listing drives and assets that you know about, they can be local to you or not, they are simply bundle metadata that allows a user to download the assets associated with the content-addressed ids. Currently we restrict package listing to git based endpoints, so users can add the listing files and discover packages. Think npm regsitry but distributed across participants.
git add bundles.json git commit -m "feat: add listing file to public repo" git push origin main
carti machine add flash --share -m output calculator-output carti machine add flash -m input calculator-input cat carti-machine-package.json
You should see this in flash drive entry
"flash_drive": [ { "cid": "baenrwig2hfjzzeqmozb7sws6tyxmyazvuipjp5hxamtllifsokwh73eucy", "start": "0x8000000000000000", "label": "root", "length": "0x3c00000", "shared": false }, { "cid": "baenrwigmw66wmp2vwjejrmmlw5sbvwpsx3zjtnd7rep4oo6wd3glahtfl4", "start": "0x9000000000000000", "label": "input", "length": "0x1000", "shared": false }, { "cid": "baenrwia5pfe7b6dvoys33k7umgsbbixgpympwcfjpqowpaye3bghmrs24m", "start": "0xa000000000000000", "label": "output", "length": "0x1000", "shared": false } ],
The machine package.json is a superset of features supported by a lua cartesi machine configuration
When we add drives we are creating a shareable superset of a lua config for running machines. cid's link back to bundles, which are assumed to be stored either locally or globally in carti_bundles/.
carti machine install ./carti-machine-package.json
With install we have created a carti_build/ directory that will serve as mountable or clear demarcation of bundles/drives that are required to run the machine
carti machine add boot "dd status=none if=\$(flashdrive input) | lua -e 'print((string.unpack(\\\"z\\\", io.read(\\\"a\\\"))))' | bc | dd status=none of=\$(flashdrive output)"
The following will generate a cartesi machine configuration file as well as easy to use runscript that will allow you to run and store the machine
carti machine build --runscript cat machine-config.lua
docker run -e USER=$(id -u -n) -e UID=$(id -u) -e GID=$(id -g) -e GROUP=$(id -g -n) \ -v $(pwd):/opt/carti -v $(pwd)/carti_build/bundles:/opt/carti/packages -it cartesi/playground /bin/bash cd /opt/carti; luapp5.3 run-config.lua machine-config
Because our configuration mounts the carti_build directory as the directory for all our drives and stuff, we can see the results of the data output to our output drive via
cat carti_build/bundles/baenrwia5pfe7b6dvoys33k7umgsbbixgpympwcfjpqowpaye3bghmrs24m/output.raw
Here we list all the external repo dependencies we might have with machine repo list
then we just simply add our
own repo to the list and call carti machine repo add
to make an entry
carti machine repo add $(echo "https://github.com/createdreamtech/carti-sample/tree/feat/complete,$(carti machine repo list)"
echo "carti_build" >> .gitignore echo "machine-config.lua" >> .gitignore echo "run-config.lua" >> .gitignore git add bundles.json git add carti-machine-package.json git push origin main
cd .. mkdir test-project cd test-project carti machine install https://github.com/createdreamtech/carti-sample/tree/feat/complete --save # the save command will save the carti-machine-package.json that was fetched # so you can then create runscripts etc... with that context. # It will overwrite existing carti-machine-package.json .
The next step would to see about the larger concepts and details. Concepts