I'm new to blockchain development. Currently, I'm learning the Ethereum platform and it sounds a very good environment to start with. I tested the web3j library on my Android application and it works fine. I used the following code to connect to my testrpc node:
Web3j web3 = Web3jFactory.build(new HttpService("http://192.168.1.108:8545"));
BigInteger gasPrice = BigInteger.valueOf(20000000000L);
BigInteger gasLimit = BigInteger.valueOf(500000L);
BigInteger nonce = null;
String contractAddress="0x0dd3b0efbce5c4eba2dc9b8500ecafb0b1cec28f";
String from = "0x2d6fcee3c3435ebda9184bdddf8481a87b7d1948";
List<Type> inputParameters = new ArrayList<>();
String hash ="232131231232141231231231231232123123123";
byte[] b =Arrays.copyOfRange(new BigInteger(hash, 16).toByteArray(), 1, 33);
Type _telNumber = new Bytes32(b);
Type _publicKey = new Bytes32(b);
inputParameters.add(_telNumber);
inputParameters.add(_publicKey);
Function function = new Function("addPerson",
inputParameters,
Collections.<TypeReference<?>>emptyList());
String functionEncoder = FunctionEncoder.encode(function);
Transaction transaction = Transaction.createFunctionCallTransaction(from, nonce,gasPrice,gasLimit,contractAddress,new BigInteger("0"), functionEncoder);
try {
EthSendTransaction transactionResponse = web3.ethSendTransaction(transaction).sendAsync().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
The above code worked and I was able to interact with a smart contract (call a function).
The main problem is that the from parameter is hardcoded (I got it from the testrpc list of accounts).
What I want to achieve: I want to create an application in which the users can create new wallets (accounts), and use them to transact with the network. I created the wallets succesfully using the following code:
String filePath = Environment.getExternalStorageDirectory().toString() + "/Pictures";
Web3j web3 = Web3jFactory.build(new HttpService("http://192.168.1.108:8545"));
Web3ClientVersion web3ClientVersion = null;
try {
String fileName = WalletUtils.generateNewWalletFile("your password",new File(filePath),false);
Log.d("FILENAME",fileName);
Credentials credentials = WalletUtils.loadCredentials(
"your password",
filePath+"/"+fileName);
myAddress = credentials.getAddress();
Log.d("My address",credentials.getAddress());
} catch (CipherException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
}
What's the next step? Should I broadcast my address to the network?
The main problem is that the from parameter is hardcoded (I got it from the testrpc list of accounts).
You can call your file and decrypt it to get your address, every time you create a new account you generate a file with your keys.
val credentialsOne = WalletUtils.loadCredentials("your password", "your path")
When you connect with your node, it will automatically detect the address
Related
I am integrating Stripe in my android application.
I have found two issues and I am stuck.
First (and major) issue is -
I have got token key from the card information. But when I tried to make my first charge, it shows error in following line.
Stripe.apiKey = "sk_test_0000000000000";
I have googled also but couldn't find any solution.
Creating Stripe Customer - cannot resolve symbol apiKey
I have even seen this kind of question too. But I failed to understand its solution.
Following is my code for making charge:
final String publishableApiKey = BuildConfig.DEBUG ?
"pk_test_000000000000000000" :
//"sk_test_00000000000000000000000" :
getString(R.string.com_stripe_publishable_key);
final TextView cardNumberField = (TextView) findViewById(R.id.cardNumber);
final TextView monthField = (TextView) findViewById(R.id.month);
final TextView yearField = (TextView) findViewById(R.id.year);
TextView cvcField = (TextView) findViewById(R.id.cvc);
Card card = new Card(cardNumberField.getText().toString(),
Integer.valueOf(monthField.getText().toString()),
Integer.valueOf(yearField.getText().toString()),
cvcField.getText().toString());
Stripe stripe = new Stripe();
stripe.createToken(card, publishableApiKey, new TokenCallback() {
public void onSuccess(Token token) {
// TODO: Send Token information to your backend to initiate a charge
Toast.makeText(
getApplicationContext(),
"Charge Token created: " + token.getId(),
Toast.LENGTH_LONG).show();
/*make a charge starts*/
// Set your secret key: remember to change this to your live secret key in production
// Create the charge on Stripe's servers - this will charge the user's card
Stripe.apiKey = "sk_test_0000000000000000000000";
try {
Map<String, Object> chargeParams = new HashMap<String, Object>();
chargeParams.put("amount", 100); // amount in cents, again
chargeParams.put("currency", "usd");
chargeParams.put("source", token.getId());
chargeParams.put("description", "Example charge");
Charge charge = Charge.create(chargeParams);
System.out.println("Charge Log :" + charge);
} catch (CardException e) {
// The card has been declined
} catch (APIException e) {
e.printStackTrace();
} catch (AuthenticationException e) {
e.printStackTrace();
} catch (InvalidRequestException e) {
e.printStackTrace();
} catch (APIConnectionException e) {
e.printStackTrace();
}
/*charge ends*/
}
I have tried these code from different examples. I followed Stripe doc too.
But I got this error:
com.stripe.exception.AuthenticationException: No API key provided. (HINT: set your API key using 'Stripe.apiKey = '.
Second Issue is - about validation.
If I am entering my own card details, and if I write wrong cvv number. It still generates token key.
I have already implemented validation of fields using Stripe's official doc. I don't know how to validate it with real time data.
Solution for the First Issue:
com.stripe.Stripe.apiKey = "sk_test_xxxxxxxxxxxxxxxxxxx";
try {
final Map<String, Object> chargeParams = new HashMap<String, Object>();
chargeParams.put("amount", 500); // amount in cents, again
chargeParams.put("currency", "usd");
chargeParams.put("source", token.getId());
chargeParams.put("description", "Example charge");
new Thread(new Runnable() {
#Override
public void run() {
Charge charge = null;
try {
charge = Charge.create(chargeParams);
} catch (AuthenticationException e) {
e.printStackTrace();
} catch (InvalidRequestException e) {
e.printStackTrace();
} catch (APIConnectionException e) {
e.printStackTrace();
} catch (CardException e) {
e.printStackTrace();
} catch (APIException e) {
e.printStackTrace();
}
System.out.println("Charge Log :" + charge);
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
Stripe's Android bindings only let you tokenize card information. Once the token has been created, it must be sent to an external server where you can use it in API requests.
You cannot use the token directly from the app as the app must never have access to your secret key, where it could easily be extracted by an attacker who would then have access to your account.
Re. your second question, the card isn't validated with the bank when the token is created (there are still some basic sanity checks, such as checking the number of digits, the fact that the expiry date is in the future, etc.). It is only when you use the token in a server-side API request that the card will be checked with the bank.
I am using the below code to create Multi user group but getting Timeout error, even if my timeout error is 10sec.
public void createGroup() {
String roomId = "Group_test003" + "#icoveri.com";
String nick = "Grouptest";
try {
MultiUserChatManager manager = multiUserChatManager.getInstanceFor(connection);
MultiUserChat muc = manager.getMultiUserChat(roomId);
muc.create(nick);
Form form = muc.getConfigurationForm();
Form submitForm = form.createAnswerForm();
List<FormField> fields = form.getFields();
for (int i = 0; i < fields.size(); i++) {
FormField field = (FormField) fields.get(i);
if (!FormField.Type.hidden.equals(field.getType()) && field.getVariable() != null) {
submitForm.setDefaultAnswer(field.getVariable());
}
}
List owners = new ArrayList();
owners.add(user1234 + "#icoveri.com");
submitForm.setAnswer("muc#roomconfig_roomowners", owners);
muc.sendConfigurationForm(submitForm);
} catch (XMPPException e) {
e.printStackTrace();
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
}
}
The error which I am getting is
org.jivesoftware.smack.SmackException$NoResponseException: No response
received within reply timeout. Timeout was 10000ms (~10s). Used
filter: AndFilter: (FromMatchesFilter (full):
Group_test003#iscoveri.com/Grouptest, StanzaTypeFilter:
org.jivesoftware.smack.packet.Presence).
at
org.jivesoftware.smack.PacketCollector.nextResultOrThrow(PacketCollector.java:229)
at
org.jivesoftware.smackx.muc.MultiUserChat.enter(MultiUserChat.java:311)
at
org.jivesoftware.smackx.muc.MultiUserChat.createOrJoin(MultiUserChat.java:400)
at
org.jivesoftware.smackx.muc.MultiUserChat.createOrJoin(MultiUserChat.java:376)
I have got the solution. The problem was in my service i.e. iscoveri.com. I had to use different service name to create the group.
I also have spent a couple hours trying to correct the same error; in my case, the problem happened when I used XMPPBOSHConnection, but not when using XMPPTCPConnection.
I've been working with Azure on the Android OS and I managed to upload my video file (.mp4) to a Container I had already prepared for it.
I did this by getting a Shared Access Signature (SAS) first, which provided me with:
a temporary key
the name of the container to where I want to send the files
the server URI
Then, I started an AsyncTask to send the file to the container using the "upload".
I checked the container, and the file gets uploaded perfectly, no problems on that end.
My question is regarding the progress of the upload. Is it possible to track it? I would like to have an upload bar to give a better UX.
P.S - I'm using the Azure Mobile SDK
Here's my code:
private void uploadFile(String filename){
mFileTransferInProgress = true;
try {
Log.d("Funky Stuff", "Blob Azure Config");
final String gFilename = filename;
File file = new File(filename); // File path
String blobUri = blobServerURL + sharedAccessSignature.replaceAll("\"", "");
StorageUri storage = new StorageUri(URI.create(blobUri));
CloudBlobClient blobCLient = new CloudBlobClient(storage);
//Container name here
CloudBlobContainer container = blobCLient.getContainerReference(blobContainer);
blob = container.getBlockBlobReference(file.getName());
//fileToByteConverter is a method to convert files to a byte[]
byte[] buffer = fileToByteConverter(file);
ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer);
if (blob != null) {
new UploadFileToAzure().execute(inputStream);
}
} catch (StorageException e) {
Log.d("Funky Stuff", "StorageException: " + e.toString());
e.printStackTrace();
} catch (IOException e) {
Log.d("Funky Stuff", "IOException: " + e.toString());
e.printStackTrace();
} catch (Exception e) {
Log.d("Funky Stuff", "Exception: " + e.toString());
e.printStackTrace();
}
mFileTransferInProgress = false;
//TODO: Missing ProgressChanged method from AWS
}
private class UploadFileToAzure extends
AsyncTask <ByteArrayInputStream, Void, Void>
{
#Override
protected Void doInBackground(ByteArrayInputStream... params) {
try {
Log.d("Funky Stuff", "Entered UploadFileToAzure Async" + uploadEvent.mFilename);
//Method to upload, takes an InputStream and a size
blob.upload(params[0], params[0].available());
params[0].close();
} catch (StorageException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Thanks!
You can split your file and send its part using Block, there is a good example of your case in this link but it used C# so you should find the corresponding function in the android library reference.
Basically instead of sending you file as one big file, you split it to multiple files (bytes) and send it to azure so you can track the progress on how many bytes that already sent to azure
I am working on android to access window azure database..
My qtn is How to make an query to access data based on single column but multiple values.?
Here is my code :
try {
mClient = new MobileServiceClient(Constant.AZURE_URL, Constant.AZURE_API_KEY, getApplicationContext());
mUsersTable = mClient.getTable(Users.class);
MobileServiceTable<Users> table = mClient.getTable(Constant.TABLE_USERS, Users.class);
table.where().field("id").eq(11)
.execute(new TableQueryCallback<Users>() {
#Override
public void onCompleted(List<Users> result, int count,
Exception exception, ServiceFilterResponse response) {
if (exception != null) {
Log.d("Exception at complete::",""+exception.getCause().getMessage());
} else {
StringBuffer sb = new StringBuffer();
for (Users users_obj : result) {
System.out.println("NAMESS::::"+users_obj.getFirstName());
// userID_arr.add(users_obj.getFirstName());
}
//System.out.println("User Array"+userID_arr);
}
}
});
} catch (MalformedURLException e) {
e.printStackTrace();
Log.e("Error Mobile Service Authentication", "There was an error creating the Mobile Service. Verify the URL");
}
catch (Exception e) {
e.printStackTrace();
}
There for I am able to get complete row on the basis of single parameter in table.where().feilds.eq(11)................... so instead 11 i want to add dynamic values on .eq() ....what is approach in Android auzre to get values on multiple id request ?
I can receive my mails with Imap with this code sample :
URLName server = new URLName("imaps://" + username + ":"+ password + "#imap.gmail.com/INBOX");
Session session = Session.getDefaultInstance(new Properties(), null);
Folder folder = session.getFolder(server);
if (folder == null)
{
System.exit(0);
}
folder.open(Folder.READ_ONLY);
Message[] messages = folder.getMessages();
But sometimes Imap doesn't give any service and at those times I want to use Pop but I couldn't use it with my code. It is different the other codes for using receive mail. But in Android only this code is working.
What should I change in this code to work with Pop?
First, there's a nice URLName constructor that takes all the component pieces as separate parameters, so you don't have to do string concatenation.
Switch from IMAP to POP3 requires changing the protocol name as well as the host name. See the JavaMail FAQ for examples. The protocol name is "pop3s" and the host name is "pop.gmail.com".
Finally, you should use Session.getInstance instead of Session.getDefaultInstance. Compare the javadocs for the two methods to understand why.
How about this one.Really worked for me!!(Source:here)
String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
Properties pop3Props = new Properties();
pop3Props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
pop3Props.setProperty("mail.pop3.socketFactory.fallback", "false");
pop3Props.setProperty("mail.pop3.port", "995");
pop3Props.setProperty("mail.pop3.socketFactory.port", "995");
URLName url = new URLName("pop3", "pop.gmail.com", 995, "","youremailid#gmail.com",yourpassword);
Session session = Session.getInstance(pop3Props, null);
Store store = new POP3SSLStore(session, url);
try {
store.connect();
} catch (MessagingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Folder folder = null;
try {
folder = store.getDefaultFolder();
folder = folder.getFolder("INBOX");
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (folder == null) {
System.exit(0);
}
try {
folder.open(Folder.READ_ONLY);
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Try retreiving folder via store object.And also mention that the folder you wish to retreive is INBOX!Also note that in settings,port number is 995 form pop.(You may leave the first six lines as they are.)