Acess variables in DAML template like in an object - daml

Okay am new to DAML and have extensive Java programming experience. Now, I have a question. In Java, 'Class A' has 'Class B', and like this, A can use 'state' of 'Class B'. I want to do something like this in DAML too.
If I think template as a class, 'contract id' is an instance of it, and the 'state' of the template (the things we declare in 'with') should be accessible in another template when passed in as a parameter, but I get compilation errors in the code I wrote.
One way to proceed is to send 'party' as a parameter instead of contract ID, and then try to access the party in contract, but I wanted to check if/ what is wrong with this!
Thanks in advance!
First template
daml 1.2
module RFP where
template RFP
with
requestorCEO: Party
where
signatory requestorCEO
Second template
daml 1.2
module InternalComm where
import RFP
template InternalComm
with
-- RFP is sent in as a parameter to this template.
rfpContractID: ContractId RFP
where
-- Here with this, I'm trying to say that the CEO who would be approving
-- an RFP is the signatory for internal communications too. It is the
-- below line that fails with compilation error.
signatory rfpContractID.requestorCEO
This is the actual error message I get for aforementioned problem. Any thoughts would be greatly appreciated!
No instance for (DA.Internal.Record.HasField
"requestorCEO" (ContractId RFP) a0)

In DAML the RFP template gives you a type RFP on which you can project out the fields (just like Java), and a type ContractId RFP which is more like a pointer to the contract on the ledger. You can "dereference" the ContractId to get the RFP using the function fetch. However, that function runs in an Update, so can't be called from a signatory. I suspect you need to change InternalComm to take a RFP without the ContractId wrapper.

This is how it worked - just remove ContractId from whole of the template.
module InternalComm where
import RFP
template InternalComm
with
-- ContractId to be removed from below line, and compilation error is resolved.
-- rfpContractID: ContractId RFP
rfpContractID: RFP
where
signatory rfpContractID.requestorCEO

Related

Using and testing FetchByKey in Daml

I have problems in retrieving contracts in Daml. Here is what I want to do:
I create an asset
I update the asset (new docs, new descriptions …)
Then I want to retrieve the last updated contract (if there are any updates, otherwise the original contract)
Finally I want to sell the last updated contract
I have created the asset and the code to update the asset. However, it's not clear to me how to use and test the fetchByKet function. So when I want to test FetchByKey to retrieve the contract, my code doesn't work.
My understanding is that I need to create an Helper template to use FetchByKey. Please my code below.
template AssetHelper
with
p : Party
where
signatory p
choice FetchAssetByKey : (ContractId Asset, Asset)
with
assetKey : (Party, Text)
controller p
do
fetchByKey #Asset assetKey
I don't know if my process is correct and I don't know how test the script as it gives me an error and it doesn't compile.
I am learning Daml for my PhD but I dont' have a background in coding.

Solidity - What version of the contract do I deploy?

I am currently learning Solidity and I have made my first BSC test contract with no errors. I have compiled my contract successfully and I am now in the deployment section of Remix.
There is a drop down menu named "contract" and within there, there are the following options:
test.sol...ApproveAndCallFallback
test.sol...BEP20Interface
test.sol...Owned
test.sol...SafeMath
test.sol...TokenBEP20
test.sol...
I am a bit confused as to which I actually deploy for my contract as there are multiple options. Could someone please point me in the right direction for descriptions of these options?
Thanks!
In the contract selectbox, you select the main contract that you want to deploy.
Most likely you have written the TokenBEP20 token and it's going to be the TokenBEP20, but it all depends on your context.

Verify and Publish Contract on Etherscan with Imported OpenZeppelin file

I'm currently building a ERC721 compliant contract and have published the contract here: https://ropsten.etherscan.io/address/0xa513bc0a0d3af384fefcd8bbc1cc0c9763307c39 - I'm now attempting to verify and publish the contract source code
The start of my file looks like so:
// SPDX-License-Identifier: MIT
// We will be using Solidity version 0.8.4
pragma solidity 0.8.4;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
contract ViperToken is ERC721 {
However, when attempting to verify and publish with a Solidity single file I have the following error appear:
ParserError: Source "#openzeppelin/contracts/token/ERC721/ERC721.sol" not found: File import callback not supported
--> myc:6:1:
|
6 | import "#openzeppelin/contracts/token/ERC721/ERC721.sol"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Can anyone point me in the direction to either 1. Solve this problem or 2. Documentation on how to appropriately write a contract that has dependencies imported that can be verified with Etherscan. Right now this is just a single file contract.
Simply put I had to go down a rabbit hole to work this out as I'm pretty new to Solidity.
I had to do the following;
Learn and use https://www.trufflesuite.com/ to setup a project and put my contract there (Using Ganache helped a lot with testing for anyone new to Solidity too)
Use HD Wallet provider package and follow tutorial here to get it on ropsten Etherscan https://medium.com/coinmonks/5-minute-guide-to-deploying-smart-contracts-with-truffle-and-ropsten-b3e30d5ee1e
Finally, use truffle-plugin-verify https://github.com/rkalis/truffle-plugin-verify to verify the contract on Etherscan
All in all, I am pretty sure there is no way within the Etherscan web app to verify a contract that contains an imported file.
The final product is here if anyone is interested in seeing how I structured it all https://github.com/lukecurtis93/viper-nft (it's just a CryptoKitties clone I found online as a base and updated it all)
If you are compiling into REMIX IDE
From REMIX IDE
Search for "Flattener" pluging
RIght click the file -> Flatten yourcontract.sol
Copy/Paste on Etherscan
I used npx hardhat flatten to compile all the code into one page, then copy and paste the code into Etherscan's single file verification. I think it is fine if you are just learning to get a feel for verifying your smart contract in Etherscan. But when it comes to production level code, I think OP's solution is better.
npx hardhat flatten gives license identifiers error when trying to verify in etherscan.
Solution is to add the below in hardhat.config.js
task("flat", "Flattens and prints contracts and their dependencies (Resolves licenses)")
.addOptionalVariadicPositionalParam("files", "The files to flatten", undefined, types.inputFile)
.setAction(async ({ files }, hre) => {
let flattened = await hre.run("flatten:get-flattened-sources", { files });
// Remove every line started with "// SPDX-License-Identifier:"
flattened = flattened.replace(/SPDX-License-Identifier:/gm, "License-Identifier:");
flattened = `// SPDX-License-Identifier: MIXED\n\n${flattened}`;
// Remove every line started with "pragma experimental ABIEncoderV2;" except the first one
flattened = flattened.replace(/pragma experimental ABIEncoderV2;\n/gm, ((i) => (m) => (!i++ ? m : ""))(0));
console.log(flattened);
});
An then run npx hardhat flat contracts/ContractToFlatten.sol > Flattened.sol

Force lex to elicit specific slot

I have multiple slots in my intent. Is it possible to force lex to elicit a specific slot using the aws sdk POSTTEXT call, and not worry about the priority of slots?
Example:
pizzaordering - intent
toppings - slot
pizzasize - slot
cheesequanity - slot
pizzaquantity - slot
When i post "25" to lex, i want it to match pizzaquantity instead of cheesequanity
Eliciting a specific slot needs to happen after Lex processes the input and sends the Event/Request to your Lambda Function during the "initialization and validation" code hook.
Without a Lambda Function, Lex will only Delegate which slots to elicit based on which ones are checked as required.
So to have more control like this, you will need a Lambda Function. You will want to read the Lambda Function Input Event and Response Formats. That shows you how Lex will pass the processed user input to your Lambda Function, and how to respond in certain ways so that you can tell Lex what to do next, such as ElicitSlot
To be clear, this is not done with the PostText API.
If you are already using a Lambda Function, then you can post the code you are using but want it to elicit a specific slot, then I could offer a more specific solution. If you don't use a Lambda Function yet, then try to set one up and you may see how to use elicitSlot yourself.
If you run into more problems, just ask another question.

Pass proxy to loaded module in a PureMVC MultiCore app?

I'm creating a flash campaign which will be loaded into a client's framework, which I have no control over. The framework will already have loaded a few things such as locale, fonts and copy, and will pass these things to my swf upon initialization.
Since the size of my swf (let's call it the shell) is restricted it will in turn display a campaign-specific preloader and then load another swf (let's call this the campaign) with the rest of the site.
The shell and the campaign will both be PureMVC modules. The shell will create a few proxies and populate these with data passed from the framework (locale constants, fonts etc), before loading in the campaign.
When the campaign is loaded it too will need locale and fonts etc. so my question is, what is the best way to pass this data along to the campaign module from the shell module?
I could create the same proxies in the campaign module and load the data again, which will be cached, but this obviously feels like the wrong way to go.
I've investigated the use of the pipes utility but this seems like a bit of an overkill in my case since the communication will be one-way and will just happen once during the initialization of the campaign.
Would it be "ok" from a design pattern point of view to pass the proxies to an init method of the campaign module and then register these proxies in the campaign module startup command? This seems wrong since these proxies have references to my shell application facade through notification names. Would it be ok if I move the notification names to some "NotificationConstants" class which both modules can use?
I could create similar proxies in the campaign module but this time populate them with the data objects from my old proxies passed to the previously mentioned init method? Spontaneously this feels like the best way to do it since the data objects don't have any references to my shell module but the "old" proxies do..
The solution I usually use is to create an interface:
interface Campaign {
function set campaignDetails(value:CampaignDetails):void;
//...
}
The campaign-module should implement this interface - in the implementation I recommend you to use a different proxy in the module, so that you would avoid having duplicated notifications and references.
When the shell is ready with the loading of the module it just has to:
if (module is Campaign)
{
(module as Campaign).campaignDetails = ...;
}
I'm sure I'm telling you nothing new. You just need to make sure to keep the acquaintance between the shell and the module only on an interface level. Then you just pass the data and leave the module MVC core to deal with it independently from the shell.