solidity add only unique string values to address mapped array - mapping

Im trying to map an string array to addresses, to store data for each address seperateluy.
the function below works only if a regular string is also parallely initiated.
my objective is to store the list of stocks for each address .
the code below works only when you also add the data on to simple string array.
what is the issue?
pragma solidity >=0.5.0 <0.9.0;
contract test{
string[] stocks;
// mapping address to a string array
mapping(address=>string[]) public portfolio;
// function to add string to mapped array only if its not present already
function addIfNotPresent(string memory tick) public {
address user=msg.sender;
uint arrayLength = stocks.length;
if(arrayLength == 0){
portfolio[user].push(tick);
//
// this code dosent work if the line below is removed
//
stocks.push(tick);
}else{
bool found=false;
for (uint i=0; i<arrayLength; i++) {
if (keccak256(abi.encodePacked(portfolio[user][i])) == keccak256(abi.encodePacked(tick))) {
found = true;
break;
}
}
if(!found){
portfolio[user].push(tick);
stocks.push(tick);
}
}
}
}```

Related

Retrieve nested mapping in Solidity

Pls, help to figure out how to retrieve the nested mapping in the Solidity.
string tokenURI;
uint256 tokenId;
There is Solidity mapping:
mapping(uint256 => mapping(address => string);
How to get all tokenURI based on address? I need to print them out using Python.
I created loop but it doesn't work:
uint256[] public tokens; // numbers 0,1,2 etc
address[] public clients; // addresses
string[] public uris;
function getNftUri() public {
for (uint256 i = 0; i < tokens.length; i++){
uint256 t = tokens[i];
for (uint256 j = 0; j < clients.length; j++){
address client = clients[j];
if (client == msg.sender){
uris.push(nftCollection2[t][client]);
}
}
}
//return uris;
}
Soldity mappings are not iterable, so you'll need to duplicate the values in an array to be able to get all values by a key.
mapping(address => mapping(uint256 => string)) tokenURIs;
// this way you can query `tokenURIsByAddress[owner]` to get all token URIs by an address
// `push()` to this array to add items
// as well as remove items from the array
mapping(address => string[]) tokenURIsByAddress;
You can also make use of some existing library for iterable mappings that does exactly the same thing as described in my code comment above.

UnimplementedFeatureError: Copying of type struct {ContractName.StructName} memory[] memory to storage not yet supported

・I want to create the lottery contract that user can buy some lottery numbers.
And, if the lottery was finished, I want to initialize it to create a new lottery.
That's why we implemented it this way.
lotChances = new LotChance[](0);
But, I faced this is error ...πŸ‘‡
UnimplementedFeatureError: Copying of type struct Lottery.LotChance memory[] memory to storage not yet supported.
Minimal example:
contract Lottery {
// Lot Structs
struct LotChance {
address payable userAddress;
uint256 ids;
}
LotChance[] public lotChances;
function getResult() public onlyOwner {
luckyPerson.transfer(address(this).balance);
lotteryId++;
lotChances = new LotChance[](0);
}
}
Please advise me😌
For reset an array and set his values to default you can use delete keyword in Solidity. In your case, you must to change your getResult() function in this way:
function getResult() public onlyOwner {
luckyPerson.transfer(address(this).balance);
lotteryId++;
delete lotChances;
}
You can see an example of smart contract code, here following:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
contract Lottery {
address owner;
constructor() {
owner = msg.sender;
}
// Lot Structs
struct LotChance {
address payable userAddress;
uint256 ids;
}
modifier onlyOwner() {
require(msg.sender == owner, "You aren't smart contract owner!");
_;
}
LotChance[] public lotChances;
function getResult(address _luckyPerson) public onlyOwner {
uint lotteryId = 0;
payable(_luckyPerson).transfer(address(this).balance);
lotteryId++;
// I reset array length about to '0'
delete lotChances;
}
function partecipateToLottery(uint _id) public {
lotChances.push(LotChance(payable(msg.sender), _id));
}
function getLengthArray() external view returns(uint) {
return lotChances.length;
}
}

Expected Primary Expression (Solidity)

I am creating a simple smart contract, however, I am getting an error on my last function ("ViewNotes") stating that the compiler was "Expected Primary Expression"? Can I not check the value at a mapping (of address => string) against the value 0 ?
My code:
pragma solidity ^0.4.4;
contract Logistics{
address public owner;
mapping(address => string) notes;
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
constructor(address genesis) public {
owner = genesis;
}
function sign(string signedNote) public onlyOwner{
notes[owner] = signedNote; //gaurenteed that msg.sender == owner
}
function transferOwnership(address nuOwner) onlyOwner {
owner = nuOwner;
}
function viewNotes(address participant) public returns(string){ // signed note on success nothing on fail
if(notes[participant] !== 0){
return (notes(participant));
}
}
}
There are a couple issues. The primary issue is that you misspelled !=. (You have an extra equals sign. !== is an operator in JavaScript, but not in Solidity.)
Once you fix that, you'll find that you can't compare a string to the number 0. You probably want to check the string's length? You'll need to cast to bytes to do that:
function viewNotes(address participant) public returns (string) {
if (bytes(notes[participant]).length != 0) {
return notes[participant];
}
}
That said, I believe this is probably equivalent to just:
function viewNotes(address participant) public returns (string) {
return notes[participant];
}
And you could instead just make notes public:
mapping(address => string) public notes;
That way, Solidity will generate a getter function for you, and people can just call notes(addr), making viewNotes redundant.
Fixing up a couple other warnings, getting rid of the modifier in favor of a direct ownership check, and assigning initial ownership to the deployer, here's my take on the contract:
pragma solidity ^0.4.24;
contract Logistics{
address public owner = msg.sender;
mapping(address => string) public notes;
function sign(string note) public {
require(msg.sender == owner);
notes[owner] = note;
}
function transferOwnership(address newOwner) public {
require(msg.sender == owner);
owner = newOwner;
}
}

C# Indexers with Ref Return Gets that also Support Sets

Am I doing something wrong here, or as of C# 7.2 Indexers that return by ref and allow set are not supported?
Works:
public ref byte this[int index] {
get {
return ref bytes[index];
}
}
Works too:
public byte this[int index] {
get {
return bytes[index];
}
set {
bytes[index] = value;
}
}
Fails:
public ref byte this[int index] {
get {
return ref bytes[index];
}
set { //<-- CS8147 Properties which return by reference cannot have set accessors
bytes[index] = value;
}
}
Fails too:
public ref byte this[int index] {
get {
return ref bytes[index];
}
}
public byte this[int index] { //<-- CS0111 Type already defines a member called 'this' with the same parameter types
set {
bytes[index] = value;
}
}
So, is there no way to have a ref return yet allow the indexer also support Set?
As #IvanStoev correctly pointed out, there is no need for set, since the value is returned by reference. Therefore the caller of the indexer has complete control over the returned value and can therefore can assign it a new value, with the changes being reflected in the underlying data structure (whose indexer was being called) since the value was returned by reference and not by value.

find out whether an email was BCC'd to me - Blackberry

My Application requires me to find out whether an incoming email was BCC'd to me or am i the direct(to,cc) recipient.
I have used the SendListener and the Address class but i am still clueless how to get what i need.
Any lead would be appreciated.
Thanks n Cheers
try this
public static String getMyEmailAddress() {
// Shared routine to get this BlackBerry's default email address
String emailAddress;
try {
Session ourSession = Session.getDefaultInstance();
// This returns null if BB does not have a Message Service - which means next
// instruction will get a null pointer exception.
emailAddress = ourSession.getServiceConfiguration().getEmailAddress();
} catch ( Exception e ) {
emailAddress = null;
}
return emailAddress;
}
public static boolean isBCCToME(){
String myEmailAddress =getMyEmailAddress();
Address[] a = msg.getRecipients(Message.RecipientType.BCC);
for (int i = 0; i < a.length; i++) {
if(a[i].equals(myEmailAddress)){
return true;
}
}
return false;
}

Resources