Creating contract within contract and accessing via Web3 - javascript

I am creating a contract (Exchange) within the Factory contract and I want to access via Web3 the Factory contract.
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
import "./Exchange.sol";
contract Factory {
mapping(address => address) public tokenToExchange;
function createExchange(address _tokenAddress) public returns (address) {
require(_tokenAddress != address(0), "invalid token address");
require(
tokenToExchange[_tokenAddress] == address(0),
"exchange already exists"
);
Exchange exchange = new Exchange(_tokenAddress);
tokenToExchange[_tokenAddress] = address(exchange);
return address(exchange);
}
function getExchange(address _tokenAddress) public view returns (address) {
return tokenToExchange[_tokenAddress];
}
}
For example, I want to addLiquidity and for that I need access to Exchange contract. But before I want to check via getExchange() function within Factory contract if the Exchange() contract is already created.
addLiquidity = async (tokenAmount: string, ethAmount: string) => {
this.setState({ loading: true });
let exchangeAddress: string;
try {
const factory = this.state.factory;
const tokenAddress = this.state.tokenAddress;
// if Exchange not already created then we will get of address(0)
0x0000000000000000000000000000000000000000
exchangeAddress = await factory.methods.getExchange(tokenAddress).call();
if (exchangeAddress.startWith('0x00') {
//Exchange address
exchangeAddress = await factory.methods
.createExchange(this.state.tokenAddress)
.call();
console.log(`Èxchange created at: ${exchangeAddress}`);
}
console.log('address already created')
} catch (err) {
console.log(err);
this.setState({ loading: false });
return;
}
If I run the function getExchange(tokenAddress) is alway return the address of address(0) 0x0000000000000000000000000000000000000000

If the return value is 0x0000000000000000000000000000000000000000 the token does not yet have an exchange.
I think that is expected.
https://docs.uniswap.org/protocol/V1/guides/connect-to-uniswap#get-exchange-address

Related

Firebase - Why is the claim not added to the user attributes?

I'm adding the claim to a user's profile that he or she paid for something, though, after the payment this attribute isn't visible. I'm running the functions on an emulator on a local host.
This is the code I'm using:
If the paypal function has been handled succesfully through paypalHandleOrder, then the function addPaidClaim is invoked.
onApprove: (data, actions) => {
paypalHandleOrder({ orderId: data.orderID }).then(
addPaidClaim(currentUser).then(
alert("THANKS FOR ORDERING!"),
// currentUser.getIdTokenResult().then(idTokenResult => {
// console.log(idTokenResult.claims)
// })
)
.catch((err) => {
return err;
})
);}
addPaidClaim is a firebase cloud function, which goes as follows:
exports.addPaidClaim = functions.https.onCall((data, context) => {
// get user and add custom claim (paid)
return admin.auth().setCustomUserClaims(data.uid, {
paid: true,
}).then(() => {
return {
message: `Success! ${data.email} has paid the course`,
};
}).catch((err) => {
return err;
});
});
I've refreshed the page and checked the user attributes afterwards through console.log on the user to see if the attribute had been added, but this is not the case. I can't find attribute paid inside the idTokenResult object. What should I do? I also find it hard to make sense of what's happening inside the function addPaidClaim. It's not returning an error when I look at the logs on my firebase console, and not much information is given, besides that the function has been invoked.
Okay, I know this question is pretty old. But I found a way just yesterday after 3 days searching over the solution. After we set up a new claim for a new user using, we need to refresh the client's getIdTokenResult(true) in the app. These are the ways I did it in Flutter Dart until a new user with updated claim managed to use it:
FirebaseAuth auth = FirebaseAuth.instance;
Future<Map<String, dynamic>> signInWithGoogle() async {
Map<String, dynamic> output = {};
final googleUser = await googleSignIn.signIn();
if (googleUser == null) {
log("Firebase => Gmail account doesn't exist");
} else {
final googleAuth = await googleUser.authentication;
final credential = GoogleAuthProvider.credential(
idToken: googleAuth.idToken,
accessToken: googleAuth.accessToken,
);
await auth.signInWithCredential(credential).then((values) async {
await userAuth(credential).then((value) =>
value.addAll(output));
});
}
return output;
}
Future<Map<String, dynamic> userAuth (OAuthCredential credential) async {
Map<String, dynamic> output = {};
await auth.currentUser!.reauthenticateWithCredential(credential);
await auth.currentUser!.reload();
await auth.currentUser!.getIdTokenResult().then((result) => {
if(result.claims!.isNotEmpty){
//check your claim here
} else {
//assign log here
}
});
return output;
}

Reference Error: "HomeSale is not defined"

I am wrote a contract in using Solidity for a real estate transaction. It will allow you to sale a house. I am currently testing the contract using Truffle and during my test i keep getting a error that says "Reference Error: Home Sale is not defined".
Here is the smart contract:
pragma solidity ^0.6.0;
contract HouseSale {
address payable _BuyerAddress;
address payable _Seller;
address payable _Agent;
struct Home{
uint _priceinBUSD;
address _owner;
bool _homeforsale;
}
Home[1] HomeDB;
modifier SellerOnly() {
require [msg.sender == _Seller];
_;
}
// set price of house
function setPriceofHouse(uint8 _home, uint256 _priceinBUSD) SellerOnly public {
HomeDB[_home].priceinBUSD;
}
function getPriceofHouse(uint8 _home, uint256 _priceinBUSD) public payable returns(uint256) {
return HomeDB[_home].priceinBUSD;
}
// buyer purchase home
function buyAHome(uint8 _home) public payable returns(uint256) {
buyerAddress = msg.sender;
//correct home price
if (msg.value % HomeDB[_home].priceinBUSD == 0 ++) msg.value > 0 ++ HomeDB)
(_home) {
uint256 FinalSalePrice = msg.value/HomeDB(_home).priceinBUSD;
_SellerAddress.transfer(msg.value);
_AgentAddress.transfer(msg.value/100);
return finalSalePrice;
}
}
}
And here is the test file
const HomeSaleTest = artifacts.require("HomeSale");
/*
* uncomment accounts to access the test accounts made available by the
* Ethereum client
* See docs: https://www.trufflesuite.com/docs/truffle/testing/writing-tests-in-javascript
*/
contract("HomeSale", function (accounts) {
let instance;
beforeEach('should setup the contract instance', async () => {
instance = await HomeSale.deployed();
});
it("should return the list of accounts", async ()=> {
console.log(accounts);
});
it("should return price", async () => {
const value = await instance.getPriceofHouse();
assert.equal(value, '10000')
});
});
I am pretty new to the test realm of Smart Contract development.
You're defining HomeSaleTest, but trying to deploy HomeSale.
const HomeSaleTest = artifacts.require("HomeSale");
// ^^ here
instance = await HomeSale.deployed();
// ^^ here
Solution: Rename either of the expressions so that they have the same name. For example:
const HomeSale = artifacts.require("HomeSale");
// ^^ here
instance = await HomeSale.deployed();
// ^^ here

TypeError: No matching declaration found after variable lookup

I am working on a simple real estate smart contract in Solidity and I keep receiving this error during testing in Truffle. " TypeError: No matching declaration found after variable lookup". The goal is to have the seller be the one to set the price of the house only.
Here is the contract code for your reference.
pragma solidity ^0.5.16;
contract HomeSale {
address payable _buyerAddress;
address payable _seller;
address payable _agent;
struct Home{
uint _priceinBUSD;
address _owner;
bool _homeforsale;
}
Home[1] HomeDB;
modifier onlySeller() {
require [msg.sender == _seller];
_;
}
// set price of house
function price(uint8 _home, uint256 _priceinBUSD) onlySeller public returns (uint64){
require(msg.sender);
HomeDB[_home].priceinBUSD;
}
function getPriceofHouse(uint8 _home, uint256 _priceinBUSD) public payable returns(uint256) {
return HomeDB[_home].priceinBUSD;
}
// buyer purchase home
function buyAHome(uint8 _home) public payable returns(uint256) {
_buyerAddress = msg.sender;
//correct home price
if (msg.value ==HomeDB[_home].priceinBUSD)(_home);
uint256 finalSalePrice = msg.value/HomeDB(_home).priceinBUSD;
_seller.transfer(msg.value);
_agent.transfer(msg.value/100);
return finalSalePrice;
}
}
Here is my test file:
const HomeSaleTest = artifacts.require("HomeSale");
/*
* uncomment accounts to access the test accounts made available by the
* Ethereum client
* See docs: https://www.trufflesuite.com/docs/truffle/testing/writing-tests-in-javascript
*/
contract("HomeSale", function (accounts) {
let instance;
beforeEach('should setup the contract instance', async () => {
instance = await HomeSale.deployed();
});
it("should return the list of accounts", async ()=> {
console.log(accounts);
});
it("should return price", async () => {
const value = await instance.getPriceofHouse();
assert.equal(value, '10000')
});
});

MSAL/ Microsoft Authorization problem with Angular: How to validate id_token?

I'm trying to make an authorization through microsoft using MSAL Angular library. I configured environment in MS Azure, wrote a code...After logging in I get id_token, but I cannot validate it on graph.microsoft.com/v1.0/me as a Bearer. I get "InvalidAuthenticationToken" code. I searched through all stack and I still can't figure it out, even though there are some familiar threads. I want to make sure token is valid and get an email of user from response. This is my code:
#Injectable()
export class MsalService {
B2CTodoAccessTokenKey = 'b2c.access.token';
tenantConfig = {
tenant: 'censored.onmicrosoft.com',
// Replace this with your client id
clientID: 'censored',
signInPolicy: 'B2C_1_signinsignup',
signUpPolicy: 'B2C_1_signin',
redirectUri: 'http://localhost:4200/auth/microsoft',
b2cScopes:
['https://censored.onmicrosoft.com/api/user_impersonation'],
resource: 'https://graph.microsoft.com'
};
/*
* B2C SignIn SignUp Policy Configuration
*/
clientApplication = new Msal.UserAgentApplication(
this.tenantConfig.clientID, this.authority,
function(errorDesc: any, token: any, error: any, tokenType: any) {
},
{
redirectUri: this.tenantConfig.redirectUri,
navigateToLoginRequestUrl: false
}
);
public login(): void {
this.clientApplication.authority =
'https://login.microsoftonline.com/common';
this.authenticate();
}
public authenticate(): void {
var _this = this;
this.clientApplication.loginPopup(this.tenantConfig.b2cScopes)
.then(function(idToken: any) {
_this.clientApplication.acquireTokenSilent(
_this.tenantConfig.b2cScopes)
.then(
function(accessToken: any) {
_this.saveAccessTokenToCache(accessToken);
}, function(error: any) {
_this.clientApplication.acquireTokenPopup(
_this.tenantConfig.b2cScopes).then(
function(accessToken: any) {
_this.saveAccessTokenToCache(accessToken);
}, function(error: any) {
console.log('error: ', error);
});
});
}, function(error: any) {
console.log('error: ', error);
});
}
First, you seem to be missing the response_type parameter, which is required for the Authorization code grant flow that you are using.
Also, you can't use the token directly but need to exchange the code you get from the response url into the token.
public static AuthenticationResult ExchangeCodeForToken(string InTenantName, string InUserObjId, string InRedirectUri, string InApplicationAzureClientID, string InApplicationAzureClientAppKey)
{
Check.Require(!string.IsNullOrEmpty(InTenantName), "InTenantName must be provided");
Check.Require(!string.IsNullOrEmpty(InUserObjId), "InUserObjId must be provided");
if (CanCompleteSignIn) //redirect from sign-in
{
var clientCredential = new ClientCredential(InApplicationAzureClientID, InApplicationAzureClientAppKey);
var authContext = new AuthenticationContext(Globals.GetLoginAuthority(InTenantName), (TokenCache)new ADALTokenCache(InUserObjId)); //Login Authority is https://login.microsoftonline.com/TenantName
return authContext.AcquireTokenByAuthorizationCode(VerificationCode, new Uri(InRedirectUri), clientCredential, Globals.AZURE_GRAPH_API_RESOURCE_ID); //RESOURCE_ID is "https://graph.microsoft.com/"
}
return null;
}
See related post.

firebase rule to allow new user to create its account object when login the very first time

I have this rule, it passed the simulated test but the client got the error "permission denied" after successfully authenticated using google. The partial rule below check for the uid object inside users object, if it doesn't exist, it is allowed to create an object
!(root.child('users').child(auth.uid).exists())
The whole rules json is below:
{
"rules":{
".read":"root.child('users').child(auth.uid).child('roles/admin').val()===true || root.child('users').child(auth.id).child('id').val()===auth.uid",
".write":"!(root.child('users').child(auth.uid).exists()) || root.child('users').child(auth.uid).child('roles/admin').val()===true || root.child('users').child(auth.id).child('id').val()===auth.uid",
}
}
The Angular code:
#Effect() loginGetUserInfo$ = this.actions$.pipe(
ofType(AuthActionTypes.AUTH_LOGIN_GET_USER_INFO),
map((action: AuthLoginGetUserInfo) => action.user),
exhaustMap((googleUser: User) => {
const ref = this.db.object('users/' + googleUser.uid);
debugger;
return ref.valueChanges().pipe(
map((user: User) => {
debugger;
if (!user) {
console.log("Is a new user:", googleUser);
//ref.set(googleUser);
ref.update(googleUser)
return new AuthLoginSuccessful(googleUser)
}
return new AuthLoginSuccessful(user)
}),
catchError(error => {debugger; return of(new AuthLoginFailure(error)) })
)
})
);
admin create new user from secondary app helped me.
FirebaseApp secondary = Firebase.app('Secondary');
final secondaryAth = FirebaseAuth.instanceFor(app: secondary);
userCreds = await secondaryAth.createUserWithEmailAndPassword(
email: email, password: password);

Categories