aiken-lang / site Goto Github PK
View Code? Open in Web Editor NEWWebsite and Docs for Aiken
Home Page: https://aiken-lang.org
License: Apache License 2.0
Website and Docs for Aiken
Home Page: https://aiken-lang.org
License: Apache License 2.0
Here is an English Auction in Aiken (https://gist.github.com/matiwinnetou/cae2685b7e88db4e310245f84b5e802c) it is one of Plutus Pioneers middle level complexity exercises. Unfortunately test coverage for it is quite low and off chain part is missing.
This task is about turning this into a proper production grade code with nearly 100% test coverage and bug fixes if there are any necessary.
Plutus Pioneers auction can be seen here:
When i copy the code for unlocking the funds i get this error:
error: Uncaught (in promise) "Insufficient collateral balance"
The problem seems to be with creating this transaction before complete() is called.
const tx = await lucid
.newTx()
.collectFrom(utxos, using)
.addSigner(await lucid.wallet.address()) // this should be beneficiary address
.validFrom(currentTime)
.validTo(laterTime)
.attachSpendingValidator(from)
.complete();
I find the use of the term bytecode
to describe the flat
encoding of UPLC confusing: It's not bytecode, it's just binary encoding of the UPLC program into some specific format (eg. flat encoding). The term bytecode should be reserved to describe instruction sets for virtual machine. This is important because whereas a bytecode-encoded program can be interpreted (or rather executed) directly, using raw bytes, against some VM "architecture", a serialised program needs first to be deserialised to be interpreted.
cmds flat and unflat are encode and decode. The options have changed
https://aiken-lang.org/uplc/cli#converting-tofrom-binary-encoding
There is an undeclared variable in the vesting_unlock.ts
script that can be found in the vesting example shown here. The variable using
in the unlock
function is not declared.
Based on the Lucid documentation, collectFrom
's second argument expects a redeemer. So I believe the code below should work.
async function unlock(ref, { from, redeemer }): Promise<TxHash> {
const [utxo] = await lucid.utxosByOutRef([ref]);
const currentTime = new Date().getTime();
const laterTime = new Date(currentTime + 2 * 60 * 60 * 1000); // add two hours (TTL: time to live)
const tx = await lucid
.newTx()
.collectFrom([utxo], redeemer) // <-- fixed here
.addSigner(await lucid.wallet.address()) // this should be beneficiary address
.validFrom(currentTime)
.validTo(laterTime)
.attachSpendingValidator(from)
.complete();
const signedTx = await tx
.sign()
.complete();
return signedTx.submit();
}
Validators:There may be one or two functions, in a single block, but no more.
Could you explain:
Hey guys, getting this error when running vesting-unlock.ts
deno run --allow-net --allow-read --allow-env .\vesting-unlock.ts
error: Uncaught (in promise) Error: Could not type cast to string/bytes.
throw new Error("Could not type cast to string/bytes.");
at castFrom (https://deno.land/x/[email protected]/src/plutus/data.ts:286:15)
at https://deno.land/x/[email protected]/src/plutus/data.ts:345:26
at Array.forEach (<anonymous>)
at castFrom (https://deno.land/x/[email protected]/src/plutus/data.ts:338:51)
at Object.from (https://deno.land/x/[email protected]/src/plutus/data.ts:188:18)
at file:///C:/Users/alfre/Documents/AIKEN/hello-world/vesting-unlock.ts:58:22
at Array.filter (<anonymous>)
at file:///C:/Users/alfre/Documents/AIKEN/hello-world/vesting-unlock.ts:57:27
at eventLoopTick (ext:core/01_core.js:168:7)
Lines 57 and 58 are the first 2 of these:
const utxos = scriptUtxos.filter((utxo) => {
let datum = Data.from(
utxo.datum,
Datum,
);
return datum.beneficiary === beneficiaryPublicKeyHash &&
datum.lock_until <= currentTime;
});
Not sure if/how to set the correct type :D
Thank you!
Relevant infos:
Problem:
The hello-world.ts
code example provided is understandably chopped in 3 pieces.
As I progressed into the example, I copied/pasted hello-world.ts
part 1 and ran it. I later added part 2 and re-ran the entire thing. Since part 1 of the code does not do anything apart from reading some parameters, all is fine. Part 2, on the other hand, starts producing an output (a transaction on-chain with an TxID).
There comes the problem for a novice: copying part 3 in the same hello-world.ts
file and run the the entire thing a third time would produce a fresh lock/unlock directly, leaving the first locking event from the second run hanging in the contract (different TxID, hence utxo reference). Some might suffer trying to unlock the first event displayed on the terminal.
Solution:
Modify the example so that lock and unlock are separated (hello-lock.ts
and hello-unlock.ts
).
User would have to manually provide the TxID of the hello-lock.ts
as utxo identifer in the hello-unlock.ts
. A safeguard could be made by writing the txLock
in a txt file.
Benefits I see:
Actual version as of April 15, 2023
I am doing the simple hello_world example -- and get this error message when I try to compile using deno.
command > deno run --allow-net --allow-read --allow-env hello_world-lock.ts
output:
error: Uncaught (in promise) TypeError: Cannot convert undefined to a BigInt
keyDeposit: BigInt(result.key_deposit),
^
at BigInt ()
at Blockfrost.getProtocolParameters (https://deno.land/x/[email protected]/src/provider/blockfrost.ts:38:19)
at async Function.new (https://deno.land/x/[email protected]/src/lucid/lucid.ts:52:34)
at async file:///home/hp/Desktop/AIKEN/hello_world/hello_world-lock.ts:13:15
According to the documentation the output should generate something like - console:
1 tADA locked into the contract at:
Tx ID: 8559f57234407204d8e9a6bf57ef6943c65ec7119eb1c2ca6224f8bad8e71c1e
Datum: d8799f581c10073fd2997d2f7dc6dadcf24966bd06b01930e5210e5de7aebf792dff
I have a Blockfrost API KEY ( input in both the .ts files )
I have :
deno 1.27.2 (release, x86_64-unknown-linux-gnu)
v8 10.8.168.4
typescript 4.8.3
I have a "preview cardano" address - addr_test1vph96epqgz5scep08muq7dxjj8cv8scxlkm0qxqkjjelxxgfckglz with demo funds
aiken checks and builds -- no problem
Any help would be appreciated as this project sparks my interest...
There are various patterns we could cover in the documentation to give people idea of what to do and what not to do with UTxO.
At least these two are wrong in the documentation:
mkNilData | (α) | (unit) | list (α)
mkPairData | (α, β) | ((α), (β)) | pair (α) (β)
Plus mkNilPairData
seems to be entirely missing.
Type signatures should agree with the output of cabal run uplc print-builtin-signatures
.
In particular for the two mentioned builtins:
mkNilData | - | (unit) | list (data)
mkPairData | - | (data, data) | pair (data) (data)
I'm a beginner in Cardano development, testing out Aiken and Lucid, and I'm currently facing issues with the tutorial located here: https://aiken-lang.org/example--vesting.
While the "Hello World" example worked fine, the 'Vesting' tutorial has been problematic, particularly when unlocking the funds. I've encountered numerous errors, primarily around the following line of code:
const tx = await lucid
.newTx()
.collectFrom(utxos, redeemer)
.addSigner(await lucid.wallet.address()) // this should be beneficiary address
.validFrom(currentTime)
.validTo(laterTime)
.attachSpendingValidator(from)
.complete();
The tutorial's example code should execute without errors, specifically the transaction should be successfully created and the funds should be unlocked as per the steps outlined in the tutorial.
Initially, The code on the examaple would not compile, i added types and fixed a variable name.
Then I received a transaction submission error:
"transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (UtxoFailure (FromAlonzoUtxoFail (OutsideValidityIntervalUTxO (ValidityInterval {invalidBefore = SJust (SlotNo 28573407), invalidHereafter = SJust (SlotNo 28580607)}) (SlotNo 28573348))))])"
if (result?.status_code === 400) throw new Error(result.message);
After addressing this by removing the .validFrom and .validTo lines to match the previous example, I started receiving another error:
error: Uncaught (in promise) "Redeemer (Spend, 0): The provided Plutus code called 'error'.\n\nExBudget {\n mem: 13835841,\n cpu: 9936288424,\n}\n\n"
Im running the tutorial code on the Preprod network. I've tried the following steps to resolve this:
Despite these attempts, the issue persists. The few times it did work, it failed again on the next try, leading me to believe that the successful attempts might have been due to luck rather than a concrete solution.
I am runnining through the Hello world tutorial and got to the point where I run deno run --allow-net --allow-read --allow-env hello_world-lock.ts
however this is throwing up the error:
Uncaught (in promise) TypeError: Cannot convert undefined to a BigInt
keyDeposit: BigInt(result.key_deposit),
^
at BigInt (<anonymous>)
at Blockfrost.getProtocolParameters (https://deno.land/x/[email protected]/src/provider/blockfrost.ts:38:19)
at async Function.new (https://deno.land/x/[email protected]/src/lucid/lucid.ts:52:34)
at async file:///D:/aiken/hello_world/hello_world-lock.ts:15:15
PS D:\aiken\hello_world> deno run --allow-net --allow-read --allow-env hello_world-lock.ts
error: Uncaught (in promise) TypeError: Cannot convert undefined to a BigInt
keyDeposit: BigInt(result.key_deposit),
^
at BigInt (<anonymous>)
at Blockfrost.getProtocolParameters (https://deno.land/x/[email protected]/src/provider/blockfrost.ts:38:19)
at async Function.new (https://deno.land/x/[email protected]/src/lucid/lucid.ts:52:34)
at async file:///D:/aiken/hello_world/hello_world-lock.ts:15:15
Row 15 of the hello_world-lock.ts file points to:
const lucid = await Lucid.new(
new Blockfrost(
"https://cardano-preview.blockfrost.io/api/v0",
Deno.env.get("XXXX")
),
"Preview"
);
Someone else has checked the Blockfrost API key and it appears to work fine for them.
1 tADA locked into the contract at: ...
in the about page the txpipe svg logo needs an update to https://txpipe.io/images/logos/txpipe.svg
The diagram on https://aiken-lang.org/uplc shouldn't say bytecode but simple "Encoded UPLC" or "Binary encoding" like in:
Thanks a lot for the examples! This combined with blockfrost free tier makes it very approachable to start programming for Cardano. After doing these two examples, I've some feedback regarding issues and possible improvements.
In this first tutorial, a lot of things are covered, I think a bit too much. It touches on:
For someone new to aiken and not fluent in JS/TS there is a lot of info. Considering there is even more TS than aiken, I'd suggest splitting this example in two. A first example would help familiarize with the setup. So that could be doing a transaction between two addresses. It would be very similar, except the core of the TS would just be this chunk:
const tx = await lucid.newTx()
.payToAddress("addr..", {lovelace: 40000000n})
.complete();
const signedTx = await tx.sign().complete();
const txHash = await signedTx.submit();
This first example would introduce the faucet, lucid on typescript and cardano scan. Then, building on that, the Hello World!
example would introduce the aiken part. It would also have the advantage that we would already have two addresses ready to be used in the Vesting
example. As otherwise, during the vesting example, one either have to do a second faucet call, or figure this transfer thing on their own between the original owner and the receiver, for the receiver to have enough funds to trigger the vesting script.
Alright that's just a general feedback. Then there is the specific issue than currently, aiken new
creates a validators/hello.ak
validator which is positioned first in the list of validators in the built plutus.json
, resulting in the locking JS code to pick the wrong validator. It wants the hello_world.ak
one, not the hello.ak
one. So we either need to change the aiken new
command to not produce that file, or the adapt the hello world example.
I've noted the following issues in the vesting example.
"found an unexpected token: 'and'"
due to the update in Aiken v1.0.14 changing the and
and or
syntax to use curly braces instead of being function calls.deno ...
commands of the page, it is missing the --allow-env
part to be able to load the blockfrost key from the evironment.lower_bound
and now
names in the contract are confusing. Especially because it's calling lower_bound
the thing that is not extracted from the transaction lower_bound time. I'd suggest something like:Finite(tx_earliest_time) -> lock_expiration_time <= tx_earliest_time
I'm not sure how to pattern match the list's rest.
Having the following code:
when foo is {
[a, ..] -> todo // I want to use `..` here
_ -> False
}
How to use the ..
in some additional logic based on the pattern match?
I would imagine something like this:
when foo is {
[a, .. as xs] -> bar(xs)
_ -> False
}
But that's not possible.
Well I could do the following as a workaround:
when foo is {
[a, ..] -> when list.tail(foo) is {
Some(b) -> bar(b)
_ -> False
}
_ -> False
}
But I don't like it since it's too verbose and includes an additional pattern match that adds more nesting.
After reviewing the codebase and trying on preprod-testnet myself, i would like to suggest the following minor improvement:
Instead of typing the txHash ourself and claiming just one vesting at a time, we should query all the UTXOs from the script address and do a simple filtering based on caller's publicKeyHash and datum's lock_until, and feed all the matching UTXOs to the TX.
let now = Date.now()
const scriptUtxos = await lucid.utxosAt(scriptAddress);
let utxos = scriptUtxos.filter((utxo) => {
let datum = Data.from<Datum>(
utxo.datum,
Datum,
);
return datum.beneficiary === beneficiaryPublicKeyHash && datum.lock_until <= now;
});
if(utxos.length === 0) { console.log("no utxo found"); return; }
const txUnlock = await unlock(utxos, { from: validator, redeemer:Data.empty() });
async function unlock(utxos, { from, redeemer }): Promise<TxHash> {
const tx = await lucid
.newTx()
.collectFrom(utxos, redeemer)
// same logic here
Thanks for you guys contribution!
[Want]
I would like to increase the number of Japanese developers by converting this document into Japanese.
https://aiken-lang.org/installation-instructions
[Reason]
I am running the Cardano developer community in Japan, but we do not have documentation in Japanese, so I'm just working on it.
http://cardanodev.jp/
Collaborator: @Akyo
Since Japanese engineers avoid Haskell, we wanted to promote Aiken and thought the best way to do so was to translate Aiken's documentation into Japanese.
I have also contributed to the Japanese language version of the hydra.family. (I hope to update this one this year.)
https://hydra.family/head-protocol/ja/
Please consider my proposal.
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.