Contract for Person Identification - ethereum

I am creating a contract for identification person, and I need to verify if there are some contracts with the same address, email, or phone number.
Example:
contract Person {
//date of create
uint public dateCreate;
//name of person
string public name;
//variables to be validates
string public email;
string public phone;
// constructor
function Person(string _name, string _email, string _phone) public {
name = _name;
email = _email;
phone = _phone;
owner = msg.sender;
}
}
I have the option to save the address contract in a mapping with the key email or phone.
contract RegisterPerson {
//save the contract address person using the key of the email
mapping(bytes32=>address) public addressEmail;
}
There is this solution, but I believe it's not the better because the mapping it will be very big and the contract expensive.
Does anybody know another solution?

You shouldn't be using a contract to represent an object like you're attempting to do here. Not only is it very costly as contract deployments are usually much more expensive than transactions, but you also can't guarantee uniqueness.
You should use a struct to represent the individual.
contract PersonStorage {
struct Person {
uint dateCreate;
string name;
string email;
string phone;
}
mapping(bytes32 => Person) persons;
function addPerson(string _name, string _email, string _phone) public {
Person memory person;
person.name = _name;
person.email = _email;
person.phone = _phone;
persons[keccak256(person.email)] = person;
}
...
}
Now, your contract is data storage for all Persons. You can deploy this version and pass the contract address to whatever contracts need access to it. You'll also have all your data centralized in case you need to allow multiple business logic contracts to use it or if you need to upgrade your business contract.
EDIT - I should note that if this is in its own contract, you'll have to change from string to bytes32. You can't send strings between contracts.

Related

How to make a new contract using remix with a function in which I want to get the user details from my already deployed contract on the blockchain

How to make a new contract using remix with a function in which I want to get the user details from my already deployed contract on the blockchain
Please be elaborate on the answer with some code as I am very new to solidity.
//deployed contract
struct User {
address wallet_address;
string userId;
string first_name;
string last_name;
}
mapping(address => User) users;
mapping(string => address) walletAccount;
mapping(address => uint) public balanceOf;
User public newUser;
uint public length;
address public owner;
constructor() public {
owner = msg.sender;
}
event userCreated (
address wallet_address,
string userId,
string first_name,
string last_name
);
function createNewUser(address userAcc, string memory _id, string memory firstName, string memory lastName) public {
User storage user = users[userAcc];
users[userAcc] = User(userAcc,_id,firstName,lastName);
}
function getUser(address _userAddress, string memory _lastName) public view returns (address, string memory, string memory, string memory) {
User memory user = users[_userAddress];
return (users[_userAddress].wallet_address, users[_userAddress].userId, users[_userAddress].first_name, users[_userAddress].last_name);
}

Solidity Programming

pragma solidity ^0.4.0;
contract crr019_week4assignment {
// Student Account Structure
struct StudentAccount {
string Username;
address Metamask;
uint Age;
string EmailAddress;
bool BlockchainTrackEnrolled;
StudentType ClassLevel;
}
constructor() public {
}
StudentAccount [] public StudentInformation;
enum StudentType {
Freshman,
Sophomore,
Junior,
Senior,
Graduate
}
function AddStudent (string _Username, address _Metamask, uint _Age, string _EmailAddress, bool _BlockchainTrackEnrolled, StudentType _ClassLevel ) public {
// Anything inside of this function can use any of the parameters
StudentAccount memory NewStudent = StudentAccount({Username:_Username, Metamask:_Metamask, Age:_Age, Email:_EmailAddress, BlockchainTrackEnrolled:_BlockchainTrackEnrolled, Student:_ClassLevel});
}
}
Getting TypeError: Named argument does not match functions declaration.
what you should correct in your smartcontract
you must add memory after your string arguments
replace email and student with EmailAddress and ClassLevel
correct code
You have a typo when you are creating your struct instance : Use EmailAddress instead of Email.
Each property name used in your json ({}) must match names declared in the struct.
The following correction has to be done in arguments and function declaration:
instead of email you must use EmailAddress
instead of Student you must use ClassLevel
for string arguments you should use memory
The corrected segment is as follow:
function AddStudent (string memory _Username, address _Metamask, uint _Age, string memory _EmailAddress, bool _BlockchainTrackEnrolled, StudentType _ClassLevel ) public {
// Anything inside of this function can use any of the parameters
StudentAccount memory NewStudent = StudentAccount({Username:_Username, Metamask:_Metamask, Age:_Age, EmailAddress:_EmailAddress, BlockchainTrackEnrolled:_BlockchainTrackEnrolled, ClassLevel:_ClassLevel});
Inside function AddStudent correct the naming convention from email to EmailAddress. Also you can add memory after each string variable(not mandatory).
Naming should be done properly.
Corrected code :
pragma solidity 0.6.12;
contract crr019_week4assignment {
// Student Account Structure
struct StudentAccount {
string Username;
address Metamask;
uint Age;
string EmailAddress;
bool BlockchainTrackEnrolled;
StudentType ClassLevel;
}
constructor() public { }
StudentAccount [] public StudentInformation;
enum StudentType {
Freshman,
Sophomore,
Junior,
Senior,
Graduate
}
function AddStudent (string memory _Username, address _Metamask, uint _Age, string memory _EmailAddress, bool _BlockchainTrackEnrolled, StudentType _ClassLevel ) public {
// Anything inside of this function can use any of the parameters
StudentAccount memory NewStudent = StudentAccount({Username:_Username, Metamask:_Metamask, Age:_Age, EmailAddress:_EmailAddress, BlockchainTrackEnrolled:_BlockchainTrackEnrolled, ClassLevel:_ClassLevel});
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract crr019_week4assignment {
// Student Account Structure
struct StudentAccount {
string Username;
address Metamask;
uint Age;
string EmailAddress;
bool BlockchainTrackEnrolled;
StudentType ClassLevel;
}
constructor() {}
StudentAccount [] public StudentInformation;
enum StudentType {
Freshman,
Sophomore,
Junior,
Senior,
Graduate
}
function addStudent (string memory _Username, address _Metamask, uint _Age, string memory _EmailAddress, bool _BlockchainTrackEnrolled, StudentType _Classlevel) public {
StudentAccount memory NewStudent = StudentAccount(_Username, _Metamask, _Age, _EmailAddress, _BlockchainTrackEnrolled, _Classlevel);
StudentInformation.push(NewStudent);
}
}

Problem on returning fields of a struct inside a mapping

I have the above code
mapping(string => Owner) public Owners;
function addOwner( string memory name, string memory surname, string memory fathername, string memory mothername, string memory ethnicityId, string memory id) public returns(int8)
{
Owner memory owner;
owner.name = name;
owner.surname = surname;
owner.fathername = fathername;
owner.mothername = mothername;
owner.ethnicityId = ethnicityId;
owner.id = id;
Owners[id] = owner;
return 0;
}
function getOwnerName(string memory id) public returns(string memory, string memory) {
Owner storage owner = Owners[id];
return (owner.name, owner.surname);
}
I am inserting an Owner with addOwner and try to retrieve with getOwnerName but Ringeby network is not returning the data I have inserted. The function returns the right data when I use the javascript VM on remix IDE

How to query a struct by multiple attributes in Solidity?

Suppose I have the following contract:
contract UserContract {
struct User {
address walletAddress;
string organisation;
string fName;
string lName;
string email;
uint index;
}
mapping(address => User) private users;
address[] private userIndex;
}
I know how to write a function that returns user information corresponding to a given address, but I'd also like to write a function that can grab user info by the User's email address.
How does this work? Is my only option to create a separate mapping for this use-case that maps the User struct to a string? If so, does this mean the struct gets stored two times? Or does it only store references to that struct?
Thanks!
If you want to do a search by either address or email (ie, NOT a composite key), then yes, the simplest option is to use two different mappings. However, struct values are stored as copies (see this for information on how mappings are stored).
To avoid extra storage for complex structs, store it in an array and use the index for the mapping values.
contract UserContract {
struct User {
address walletAddress;
string organisation;
string fName;
string lName;
string email;
uint index;
}
User[] users;
mapping(address => uint256) private addressMap;
mapping(string => uint256) private emailMap; // Note this must be private if you’re going to use `string` as the key. Otherwise, use bytes32
address[] private userIndex;
}

rest api returns empty bracket for GET request

I implemented Rest api with Spring Boot. In my controller class, I have code to handle GET request which will return JSON if record found.
// SeqController.java
#Autowired
private SeqService seqService;
#RequestMapping(
value = "/api/seqs/{analysis_id}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<SeqTb>> getSeqByAnalysisId(#PathVariable("analysis_id") String analysis_id) {
List<SeqTb> seqs = seqService.findByAnalysisId(analysis_id);
return new ResponseEntity(seqs, HttpStatus.OK);
}
I also create a bean class SeqServiceBean that extends the interface SeqService which in turn calls methods from the following JPA repository for query.
//SeqRepository.java
#Repository
public interface SeqRepository extends JpaRepository<SeqTb, Integer> {
#Override
public List<SeqTb> findAll();
public List<SeqTb> findByAnalysisId(String analysisId);
}
Problem is when I typed the url (http://localhost:8080/api/seqs/fdebfd6e-d046-4192-8b97-ac9f65dc2009) in my browser, it returned nothing but a pair of empty brackets. I just looked in the database and that record is indeed there. What did I do wrong?
A bit late to answer this quesiton, but in case anyone else is having this issue.
This problem may be caused by the class (that we want to be displayed as a json object) missing getter and/or setter methods.
In your case the "seqTab" class may be not have getters.
Without the getters our application can not extract the fileds to build the json object.
Example :
Sample user class
public class User {
private String firstname;
private String lasttname;
int age;
public User(){
}
public User(String fname, String lname, int age){
this.firstname = fname;
this.lasttname = lname;
this.age = age;
}
}
Sample rest controller
#RestController
public class SampleRS {
#RequestMapping(value = {"/sample/{input}"}, method = RequestMethod.GET , produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<User> startService(#PathVariable("input") String input){
User u = new User(input,"bikila",45);
return new ResponseEntity<User>(u,HttpStatus.OK);
}
}
// If we try to hit the endpoint /sample{input} .. e.g.
Request : localhost:8080/Sample/abebe
Response :
{}
But adding the getters for the User class will solve the problem.
Modified User class with getters
public class User {
private String firstname;
private String lasttname;
int age;
public User(){
}
public User(String fname, String lname, int age){
this.firstname = fname;
this.lasttname = lname;
this.age = age;
}
public String getFirstname() {
return firstname;
}
public String getLasttname() {
return lasttname;
}
public int getAge() {
return age;
}
}
Request : http://localhost:8080/sample/abebe
Response : {"firstname":"abebe","lasttname":"bikila","age":45}
Hope that helps !
In most of case, database driver jar is not deployed in server. Check deployment assembly of project in eclipse. Also see console message to check if it is showing driver jar not found.
If this is case simply deploy this jar in deployment assembly of eclipse.
One thing, if build path has this jdbc driverjar in eclipse, main method will connect to database. But if jar is not deployed jdbc connection will not happen over http request.